autocomit
This commit is contained in:
@@ -0,0 +1,447 @@
|
||||
# Story 0: Foundation - Walking Skeleton
|
||||
|
||||
## Story Overview
|
||||
|
||||
**As a** development team
|
||||
**I want** to establish the technical foundation and development patterns
|
||||
**So that** all future features can be built consistently and efficiently
|
||||
|
||||
**Story Type**: Technical Foundation
|
||||
**Priority**: Highest
|
||||
**Estimated Effort**: 2-3 weeks
|
||||
**Dependencies**: None (first story)
|
||||
|
||||
---
|
||||
|
||||
## Business Value
|
||||
|
||||
This story establishes:
|
||||
- Complete tech stack setup (Spring Boot + Angular + PostgreSQL)
|
||||
- Authentication and authorization framework
|
||||
- One complete CRUD example (Environment entity) as a template
|
||||
- CI/CD pipeline foundation
|
||||
- Testing infrastructure
|
||||
- Development patterns for all future stories
|
||||
|
||||
---
|
||||
|
||||
## Scope
|
||||
|
||||
### In Scope
|
||||
✅ Spring Boot project setup with security
|
||||
✅ PostgreSQL database with Liquibase
|
||||
✅ JWT authentication implementation
|
||||
✅ Angular project setup
|
||||
✅ Authentication UI (login page)
|
||||
✅ Environment entity (complete CRUD) as pattern example
|
||||
✅ API documentation (Swagger)
|
||||
✅ Docker setup for local development
|
||||
✅ Basic CI/CD configuration
|
||||
|
||||
### Out of Scope
|
||||
❌ All business entities except Environment
|
||||
❌ Complex authorization rules (just basic role check)
|
||||
❌ OAuth integration (local auth only)
|
||||
❌ Advanced UI features
|
||||
|
||||
---
|
||||
|
||||
## Technical Implementation
|
||||
|
||||
### Backend Tasks
|
||||
|
||||
#### 1. Project Setup
|
||||
- [ ] Create Spring Boot project via Spring Initializr
|
||||
- Spring Boot 3.2.x
|
||||
- Dependencies: Web, Security, JPA, PostgreSQL, Liquibase, Validation
|
||||
- [ ] Configure `pom.xml` with additional dependencies
|
||||
- JJWT for JWT handling
|
||||
- Lombok
|
||||
- SpringDoc OpenAPI
|
||||
- Testcontainers
|
||||
- [ ] Setup project structure (packages: config, domain, repository, service, dto, controller, security, exception)
|
||||
|
||||
#### 2. Database Setup
|
||||
- [ ] Create Liquibase changelog master file
|
||||
- [ ] Migration 001: Create `user` table with columns:
|
||||
- `id` (UUID, PK)
|
||||
- `username` (VARCHAR, unique, not null)
|
||||
- `password` (VARCHAR, hashed, not null)
|
||||
- `email` (VARCHAR, unique, not null)
|
||||
- `role` (VARCHAR, not null) - Simple role: ADMIN, USER
|
||||
- `created_at`, `updated_at` (TIMESTAMP)
|
||||
- [ ] Migration 002: Create `environment` table with columns:
|
||||
- `id` (UUID, PK)
|
||||
- `name` (VARCHAR, unique, not null)
|
||||
- `description` (TEXT, nullable)
|
||||
- `is_production` (BOOLEAN, default false)
|
||||
- `criticality_level` (INTEGER, nullable)
|
||||
- `created_at`, `updated_at` (TIMESTAMP)
|
||||
- [ ] Add indexes on `is_production` and `name`
|
||||
|
||||
#### 3. JPA Entities
|
||||
- [ ] Create `BaseEntity` abstract class with:
|
||||
- `id` field with UUID generator
|
||||
- `createdAt`, `updatedAt` with JPA auditing
|
||||
- [ ] Create `User` entity extending `BaseEntity`
|
||||
- [ ] Create `Environment` entity extending `BaseEntity`
|
||||
- [ ] Configure JPA auditing in configuration class
|
||||
|
||||
#### 4. Security Implementation
|
||||
- [ ] Create `JwtTokenProvider` class
|
||||
- `generateToken(Authentication)`: Create JWT token
|
||||
- `getUsernameFromToken(String)`: Extract username
|
||||
- `validateToken(String)`: Validate token
|
||||
- [ ] Create `JwtAuthenticationFilter` extends `OncePerRequestFilter`
|
||||
- Extract JWT from Authorization header
|
||||
- Validate token
|
||||
- Set authentication in SecurityContext
|
||||
- [ ] Create `UserDetailsServiceImpl` implements `UserDetailsService`
|
||||
- Load user from database
|
||||
- Map to Spring Security UserDetails
|
||||
- [ ] Create `SecurityConfig`
|
||||
- Configure HTTP security
|
||||
- Disable CSRF (stateless API)
|
||||
- Configure CORS
|
||||
- Set session management to STATELESS
|
||||
- Define public endpoints: `/api/auth/**`
|
||||
- Require authentication for all other endpoints
|
||||
- Add JWT filter before UsernamePasswordAuthenticationFilter
|
||||
- [ ] Create `AuthController` with endpoints:
|
||||
- `POST /api/auth/register`: Register new user
|
||||
- `POST /api/auth/login`: Authenticate and return JWT
|
||||
- `GET /api/auth/me`: Get current user info
|
||||
|
||||
#### 5. Environment CRUD (Pattern Example)
|
||||
- [ ] Create `EnvironmentRepository` extends `JpaRepository<Environment, UUID>`
|
||||
- [ ] Create DTOs:
|
||||
- `CreateEnvironmentRequest` (name, description, isProduction, criticalityLevel)
|
||||
- `UpdateEnvironmentRequest` (same as create, all optional)
|
||||
- `EnvironmentResponse` (all fields + createdAt, updatedAt)
|
||||
- [ ] Create `EnvironmentService` with methods:
|
||||
- `create(CreateEnvironmentRequest)`: Create new environment
|
||||
- `update(UUID, UpdateEnvironmentRequest)`: Update environment
|
||||
- `findById(UUID)`: Get by ID
|
||||
- `findAll(Pageable)`: List all with pagination
|
||||
- `delete(UUID)`: Delete environment
|
||||
- [ ] Create `EnvironmentController` with endpoints:
|
||||
- `GET /api/environments`: List all (with pagination, sorting)
|
||||
- `GET /api/environments/{id}`: Get by ID
|
||||
- `POST /api/environments`: Create new
|
||||
- `PUT /api/environments/{id}`: Update
|
||||
- `DELETE /api/environments/{id}`: Delete
|
||||
- [ ] Add validation annotations on DTOs
|
||||
- [ ] Add Swagger annotations on controller methods
|
||||
|
||||
#### 6. Exception Handling
|
||||
- [ ] Create custom exceptions:
|
||||
- `ResourceNotFoundException`
|
||||
- `BadRequestException`
|
||||
- `UnauthorizedException`
|
||||
- [ ] Create `GlobalExceptionHandler` with `@ControllerAdvice`
|
||||
- Handle all custom exceptions
|
||||
- Return standardized error response (status, message, timestamp)
|
||||
|
||||
#### 7. Configuration
|
||||
- [ ] Configure `application.yml` for database, JPA, Liquibase
|
||||
- [ ] Configure `application-dev.yml` for development
|
||||
- [ ] Configure `application-prod.yml` for production
|
||||
- [ ] Create `OpenApiConfig` for Swagger documentation
|
||||
- [ ] Create `CorsConfig` for frontend integration
|
||||
|
||||
#### 8. Testing
|
||||
- [ ] Unit tests for `EnvironmentService` (with Mockito)
|
||||
- [ ] Integration tests for `EnvironmentController` (with Testcontainers)
|
||||
- [ ] Security tests for JWT authentication flow
|
||||
- [ ] Test coverage > 80%
|
||||
|
||||
---
|
||||
|
||||
### Frontend Tasks
|
||||
|
||||
#### 1. Project Setup
|
||||
- [ ] Create Angular 18 project: `ng new ldpv2-frontend`
|
||||
- [ ] Add Angular Material or PrimeNG
|
||||
- [ ] Configure TypeScript strict mode
|
||||
- [ ] Setup proxy configuration for API calls
|
||||
- [ ] Configure environments (dev, prod)
|
||||
|
||||
#### 2. Project Structure
|
||||
- [ ] Create folder structure:
|
||||
- `core/` (auth, guards, interceptors, services)
|
||||
- `shared/` (models, components, pipes)
|
||||
- `features/` (feature modules)
|
||||
- [ ] Setup routing module
|
||||
|
||||
#### 3. Authentication Module
|
||||
- [ ] Create models:
|
||||
- `User` interface (id, username, email, role)
|
||||
- `LoginRequest` interface (username, password)
|
||||
- `LoginResponse` interface (token, user)
|
||||
- [ ] Create `AuthService`:
|
||||
- `login(credentials)`: Call login API, store JWT in localStorage
|
||||
- `logout()`: Clear JWT from localStorage
|
||||
- `isAuthenticated()`: Check if JWT exists and is valid
|
||||
- `getCurrentUser()`: Get current user from token
|
||||
- [ ] Create `JwtInterceptor` (implements `HttpInterceptor`):
|
||||
- Add Authorization header with JWT to all requests
|
||||
- [ ] Create `ErrorInterceptor` (implements `HttpInterceptor`):
|
||||
- Handle 401 (redirect to login)
|
||||
- Handle other errors (show notification)
|
||||
- [ ] Create `AuthGuard` (implements `CanActivate`):
|
||||
- Protect routes requiring authentication
|
||||
- Redirect to login if not authenticated
|
||||
- [ ] Create `LoginComponent`:
|
||||
- Reactive form with username and password
|
||||
- Call AuthService.login()
|
||||
- Redirect to dashboard on success
|
||||
- Show error message on failure
|
||||
|
||||
#### 4. Environment Management (Pattern Example)
|
||||
- [ ] Create `Environment` model (TypeScript interface)
|
||||
- [ ] Create `EnvironmentService`:
|
||||
- `getEnvironments(page, size, sort)`: GET /api/environments
|
||||
- `getEnvironment(id)`: GET /api/environments/{id}
|
||||
- `createEnvironment(data)`: POST /api/environments
|
||||
- `updateEnvironment(id, data)`: PUT /api/environments/{id}
|
||||
- `deleteEnvironment(id)`: DELETE /api/environments/{id}
|
||||
- [ ] Create `EnvironmentListComponent`:
|
||||
- Display environments in table/list
|
||||
- Pagination controls
|
||||
- Sort by name, criticality, etc.
|
||||
- Actions: View, Edit, Delete
|
||||
- Button: Create New
|
||||
- [ ] Create `EnvironmentDetailComponent`:
|
||||
- Display full environment details
|
||||
- Edit and Delete buttons
|
||||
- [ ] Create `EnvironmentFormComponent`:
|
||||
- Reactive form for create/edit
|
||||
- Validation (required fields, unique name)
|
||||
- Submit to API
|
||||
- Success/error notifications
|
||||
- [ ] Add routing:
|
||||
- `/environments`: EnvironmentListComponent
|
||||
- `/environments/new`: EnvironmentFormComponent (create mode)
|
||||
- `/environments/:id`: EnvironmentDetailComponent
|
||||
- `/environments/:id/edit`: EnvironmentFormComponent (edit mode)
|
||||
|
||||
#### 5. Shared Components
|
||||
- [ ] Create `HeaderComponent` (navigation, user menu, logout)
|
||||
- [ ] Create `LoadingSpinnerComponent`
|
||||
- [ ] Create `ConfirmDialogComponent` (for delete confirmations)
|
||||
- [ ] Create `NotificationService` (toast notifications)
|
||||
|
||||
#### 6. Styling
|
||||
- [ ] Setup global styles
|
||||
- [ ] Create responsive layout
|
||||
- [ ] Style login page
|
||||
- [ ] Style environment management pages
|
||||
|
||||
#### 7. Testing
|
||||
- [ ] Unit tests for `AuthService`
|
||||
- [ ] Unit tests for `EnvironmentService`
|
||||
- [ ] Component tests for `LoginComponent`
|
||||
- [ ] Component tests for `EnvironmentListComponent`
|
||||
- [ ] E2E test: Login flow
|
||||
- [ ] E2E test: Create environment flow
|
||||
- [ ] Test coverage > 70%
|
||||
|
||||
---
|
||||
|
||||
### DevOps Tasks
|
||||
|
||||
#### 1. Docker Setup
|
||||
- [ ] Create `Dockerfile` for backend
|
||||
- [ ] Create `Dockerfile` for frontend
|
||||
- [ ] Create `docker-compose.yml` with services:
|
||||
- PostgreSQL
|
||||
- Backend
|
||||
- Frontend (optional for dev)
|
||||
- [ ] Document how to run with Docker
|
||||
|
||||
#### 2. CI/CD Pipeline
|
||||
- [ ] Create `.gitlab-ci.yml` or `Jenkinsfile` or GitHub Actions workflow
|
||||
- [ ] Pipeline stages:
|
||||
- Build (backend and frontend)
|
||||
- Test (run all tests)
|
||||
- Code quality check (SonarQube optional)
|
||||
- Build Docker images
|
||||
- Push to registry (optional)
|
||||
- [ ] Configure environment variables
|
||||
|
||||
#### 3. Documentation
|
||||
- [ ] README.md with:
|
||||
- Project description
|
||||
- Prerequisites
|
||||
- How to run locally
|
||||
- How to run with Docker
|
||||
- How to run tests
|
||||
- [ ] API documentation accessible via Swagger UI
|
||||
- [ ] Contribution guidelines (optional)
|
||||
|
||||
---
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
### Authentication
|
||||
- [ ] User can register a new account
|
||||
- [ ] User can login with username and password
|
||||
- [ ] Upon successful login, JWT token is returned
|
||||
- [ ] JWT token is stored in browser (localStorage)
|
||||
- [ ] JWT token is automatically included in API requests
|
||||
- [ ] User is redirected to login page when token is invalid/expired
|
||||
- [ ] User can logout (token is cleared)
|
||||
|
||||
### Environment CRUD
|
||||
- [ ] User can view a list of all environments
|
||||
- [ ] List is paginated (20 items per page)
|
||||
- [ ] User can sort environments by name or criticality
|
||||
- [ ] User can view details of a specific environment
|
||||
- [ ] User can create a new environment with:
|
||||
- Name (required, unique)
|
||||
- Description (optional)
|
||||
- Production flag (default: false)
|
||||
- Criticality level (optional, 1-5)
|
||||
- [ ] Form validation works correctly (required fields, unique name)
|
||||
- [ ] User can edit an existing environment
|
||||
- [ ] User can delete an environment (with confirmation dialog)
|
||||
- [ ] Success and error notifications are displayed appropriately
|
||||
|
||||
### API Documentation
|
||||
- [ ] Swagger UI is accessible at `/swagger-ui/index.html`
|
||||
- [ ] All endpoints are documented with request/response schemas
|
||||
- [ ] Authentication endpoints are documented
|
||||
- [ ] Environment endpoints are documented
|
||||
|
||||
### Testing
|
||||
- [ ] Backend unit tests pass (>80% coverage)
|
||||
- [ ] Backend integration tests pass
|
||||
- [ ] Frontend unit tests pass (>70% coverage)
|
||||
- [ ] E2E tests pass for critical flows
|
||||
|
||||
### DevOps
|
||||
- [ ] Application runs successfully with `docker-compose up`
|
||||
- [ ] CI/CD pipeline builds and tests successfully
|
||||
- [ ] README documentation is complete and accurate
|
||||
|
||||
---
|
||||
|
||||
## Testing Scenarios
|
||||
|
||||
### Scenario 1: User Registration and Login
|
||||
1. Navigate to registration page
|
||||
2. Fill in username, email, password
|
||||
3. Submit registration form
|
||||
4. Verify success message
|
||||
5. Navigate to login page
|
||||
6. Enter username and password
|
||||
7. Submit login form
|
||||
8. Verify redirect to dashboard
|
||||
9. Verify JWT token in localStorage
|
||||
10. Verify Authorization header in subsequent requests
|
||||
|
||||
### Scenario 2: Create Environment
|
||||
1. Login as authenticated user
|
||||
2. Navigate to environments list
|
||||
3. Click "Create New Environment"
|
||||
4. Fill in form:
|
||||
- Name: "PROD-EU"
|
||||
- Description: "Production environment for Europe"
|
||||
- Production: true
|
||||
- Criticality: 5
|
||||
5. Submit form
|
||||
6. Verify success notification
|
||||
7. Verify redirect to environment list
|
||||
8. Verify new environment appears in list
|
||||
|
||||
### Scenario 3: Edit Environment
|
||||
1. Navigate to environment list
|
||||
2. Click "Edit" on an environment
|
||||
3. Modify description
|
||||
4. Submit form
|
||||
5. Verify success notification
|
||||
6. Verify changes are reflected
|
||||
|
||||
### Scenario 4: Delete Environment
|
||||
1. Navigate to environment list
|
||||
2. Click "Delete" on an environment
|
||||
3. Confirm deletion in dialog
|
||||
4. Verify success notification
|
||||
5. Verify environment is removed from list
|
||||
|
||||
### Scenario 5: Unauthorized Access
|
||||
1. Logout or clear JWT token
|
||||
2. Attempt to access protected route (e.g., `/environments`)
|
||||
3. Verify redirect to login page
|
||||
4. Login again
|
||||
5. Verify redirect to originally requested page
|
||||
|
||||
---
|
||||
|
||||
## Definition of Done
|
||||
|
||||
- [ ] All backend tasks completed
|
||||
- [ ] All frontend tasks completed
|
||||
- [ ] All DevOps tasks completed
|
||||
- [ ] All acceptance criteria met
|
||||
- [ ] All tests passing (unit, integration, E2E)
|
||||
- [ ] Code reviewed and approved
|
||||
- [ ] API documented in Swagger
|
||||
- [ ] User documentation updated
|
||||
- [ ] Demo conducted successfully
|
||||
- [ ] Code merged to main branch
|
||||
|
||||
---
|
||||
|
||||
## Technical Debt & Future Improvements
|
||||
|
||||
### Known Limitations
|
||||
- Simple role-based authorization (ADMIN, USER) - will need environment-specific roles in future
|
||||
- Local authentication only - OAuth integration planned for later
|
||||
- Basic error handling - can be enhanced with more specific error codes
|
||||
- No password reset functionality - to be added later
|
||||
|
||||
### Future Enhancements
|
||||
- Implement refresh token mechanism
|
||||
- Add password strength validation
|
||||
- Implement account activation via email
|
||||
- Add "Remember me" functionality
|
||||
- Implement rate limiting on auth endpoints
|
||||
- Add audit logging for security events
|
||||
|
||||
---
|
||||
|
||||
## Dependencies & Blockers
|
||||
|
||||
### Dependencies
|
||||
None - this is the first story
|
||||
|
||||
### Potential Blockers
|
||||
- PostgreSQL setup issues → Use Docker Compose
|
||||
- CORS configuration issues → Properly configure allowed origins
|
||||
- JWT secret management → Use environment variables
|
||||
- Network connectivity between services → Use Docker network
|
||||
|
||||
---
|
||||
|
||||
## Resources & References
|
||||
|
||||
### Spring Boot Documentation
|
||||
- [Spring Security](https://docs.spring.io/spring-security/reference/index.html)
|
||||
- [Spring Data JPA](https://docs.spring.io/spring-data/jpa/docs/current/reference/html/)
|
||||
- [Liquibase with Spring Boot](https://docs.liquibase.com/tools-integrations/springboot/springboot.html)
|
||||
|
||||
### Angular Documentation
|
||||
- [Angular Authentication](https://angular.io/guide/security)
|
||||
- [HTTP Interceptors](https://angular.io/guide/http-interceptor-use-cases)
|
||||
- [Reactive Forms](https://angular.io/guide/reactive-forms)
|
||||
|
||||
### JWT
|
||||
- [JJWT Library](https://github.com/jwtk/jjwt)
|
||||
- [JWT Best Practices](https://tools.ietf.org/html/rfc8725)
|
||||
|
||||
---
|
||||
|
||||
**Story Status**: Ready for Development
|
||||
**Story Created**: February 2026
|
||||
**Estimated Completion**: 2-3 weeks from start
|
||||
@@ -0,0 +1,500 @@
|
||||
# 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<BusinessUnit, UUID> {
|
||||
Optional<BusinessUnit> findByName(String name);
|
||||
boolean existsByName(String name);
|
||||
Page<BusinessUnit> 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<BusinessUnitResponse> findAll(Pageable pageable);
|
||||
Page<BusinessUnitResponse> 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<Page<BusinessUnit>>
|
||||
searchBusinessUnits(query, page, size): Observable<Page<BusinessUnit>>
|
||||
getBusinessUnit(id): Observable<BusinessUnit>
|
||||
createBusinessUnit(data): Observable<BusinessUnit>
|
||||
updateBusinessUnit(id, data): Observable<BusinessUnit>
|
||||
deleteBusinessUnit(id): Observable<void>
|
||||
}
|
||||
```
|
||||
|
||||
#### 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
|
||||
@@ -0,0 +1,541 @@
|
||||
# Story 2: Application Management
|
||||
|
||||
## Story Overview
|
||||
|
||||
**As a** application manager
|
||||
**I want** to manage applications in the system
|
||||
**So that** I can track all applications and their lifecycle status
|
||||
|
||||
**Story Type**: Feature (Core Domain)
|
||||
**Priority**: Highest
|
||||
**Estimated Effort**: 5-7 days
|
||||
**Dependencies**: Story 1 (Business Units)
|
||||
|
||||
---
|
||||
|
||||
## Business Value
|
||||
|
||||
Applications are the central entity in LDPv2. This story enables:
|
||||
- Complete application inventory
|
||||
- Lifecycle status tracking (IDEA → IN_DEVELOPMENT → IN_SERVICE → MAINTENANCE → DECOMMISSIONED)
|
||||
- Business unit ownership
|
||||
- Foundation for deployment tracking (Story 6)
|
||||
- End-of-life and support tracking
|
||||
|
||||
---
|
||||
|
||||
## Scope
|
||||
|
||||
### In Scope
|
||||
✅ Application CRUD operations
|
||||
✅ Lifecycle status management
|
||||
✅ Business unit association
|
||||
✅ End-of-life and end-of-support date tracking
|
||||
✅ Application search and filtering
|
||||
✅ Status-based filtering
|
||||
|
||||
### Out of Scope
|
||||
❌ Version management (Story 5)
|
||||
❌ Deployment tracking (Story 6)
|
||||
❌ Contact/stakeholder management (Story 3)
|
||||
❌ SLA management (Phase 2)
|
||||
❌ Technical documentation (Phase 2)
|
||||
❌ External dependencies (Phase 2)
|
||||
|
||||
---
|
||||
|
||||
## Technical Implementation
|
||||
|
||||
### Backend Tasks
|
||||
|
||||
#### 1. Database Migration
|
||||
- [ ] Create Liquibase migration: `004-create-application-tables.xml`
|
||||
- [ ] Create `application` table:
|
||||
```sql
|
||||
- id (UUID, PK)
|
||||
- name (VARCHAR(255), not null)
|
||||
- description (TEXT, nullable)
|
||||
- status (VARCHAR(50), not null) -- IDEA, IN_DEVELOPMENT, IN_SERVICE, MAINTENANCE, DECOMMISSIONED
|
||||
- business_unit_id (UUID, FK to business_unit, not null)
|
||||
- end_of_life_date (DATE, nullable)
|
||||
- end_of_support_date (DATE, nullable)
|
||||
- created_at (TIMESTAMP, not null)
|
||||
- updated_at (TIMESTAMP, not null)
|
||||
```
|
||||
- [ ] Add indexes:
|
||||
- `idx_application_status` on status
|
||||
- `idx_application_business_unit` on business_unit_id
|
||||
- `idx_application_name` on name (for search)
|
||||
- [ ] Add foreign key constraint: `business_unit_id` → `business_unit(id)`
|
||||
- [ ] Insert sample data (5-10 applications with various statuses)
|
||||
|
||||
#### 2. Enum
|
||||
- [ ] Create `ApplicationStatus` enum:
|
||||
```java
|
||||
public enum ApplicationStatus {
|
||||
IDEA("Idea"),
|
||||
IN_DEVELOPMENT("In Development"),
|
||||
IN_SERVICE("In Service"),
|
||||
MAINTENANCE("Maintenance"),
|
||||
DECOMMISSIONED("Decommissioned");
|
||||
|
||||
private final String displayName;
|
||||
// Constructor, getter
|
||||
}
|
||||
```
|
||||
|
||||
#### 3. JPA Entity
|
||||
- [ ] Create `Application` entity extending `BaseEntity`:
|
||||
```java
|
||||
@Entity
|
||||
@Table(name = "application")
|
||||
public class Application extends BaseEntity {
|
||||
@Column(nullable = false)
|
||||
private String name;
|
||||
|
||||
@Column(columnDefinition = "TEXT")
|
||||
private String description;
|
||||
|
||||
@Enumerated(EnumType.STRING)
|
||||
@Column(nullable = false, length = 50)
|
||||
private ApplicationStatus status;
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "business_unit_id", nullable = false)
|
||||
private BusinessUnit businessUnit;
|
||||
|
||||
@Column(name = "end_of_life_date")
|
||||
private LocalDate endOfLifeDate;
|
||||
|
||||
@Column(name = "end_of_support_date")
|
||||
private LocalDate endOfSupportDate;
|
||||
|
||||
// Getters, setters, constructors
|
||||
}
|
||||
```
|
||||
|
||||
#### 4. Repository Layer
|
||||
- [ ] Create `ApplicationRepository`:
|
||||
```java
|
||||
public interface ApplicationRepository extends JpaRepository<Application, UUID> {
|
||||
Page<Application> findByStatus(ApplicationStatus status, Pageable pageable);
|
||||
Page<Application> findByBusinessUnitId(UUID businessUnitId, Pageable pageable);
|
||||
Page<Application> findByNameContainingIgnoreCase(String name, Pageable pageable);
|
||||
Page<Application> findByStatusAndBusinessUnitId(ApplicationStatus status, UUID businessUnitId, Pageable pageable);
|
||||
|
||||
@Query("SELECT a FROM Application a WHERE " +
|
||||
"(:status IS NULL OR a.status = :status) AND " +
|
||||
"(:businessUnitId IS NULL OR a.businessUnit.id = :businessUnitId) AND " +
|
||||
"(:name IS NULL OR LOWER(a.name) LIKE LOWER(CONCAT('%', :name, '%')))")
|
||||
Page<Application> search(
|
||||
@Param("status") ApplicationStatus status,
|
||||
@Param("businessUnitId") UUID businessUnitId,
|
||||
@Param("name") String name,
|
||||
Pageable pageable
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
#### 5. DTOs
|
||||
- [ ] Create `CreateApplicationRequest`:
|
||||
- `name` (required, max 255 chars)
|
||||
- `description` (optional)
|
||||
- `status` (required, default: IDEA)
|
||||
- `businessUnitId` (required, UUID)
|
||||
- `endOfLifeDate` (optional, LocalDate)
|
||||
- `endOfSupportDate` (optional, LocalDate)
|
||||
- [ ] Create `UpdateApplicationRequest`:
|
||||
- All fields optional (partial update support)
|
||||
- [ ] Create `ApplicationResponse`:
|
||||
- `id`, `name`, `description`, `status`, `businessUnit` (summary), `endOfLifeDate`, `endOfSupportDate`, `createdAt`, `updatedAt`
|
||||
- [ ] Create `ApplicationSummaryResponse` (for lists):
|
||||
- `id`, `name`, `status`, `businessUnitName`
|
||||
- [ ] Create `BusinessUnitSummaryDto`:
|
||||
- `id`, `name`
|
||||
|
||||
#### 6. Service Layer
|
||||
- [ ] Create `ApplicationService` with methods:
|
||||
```java
|
||||
ApplicationResponse create(CreateApplicationRequest request);
|
||||
ApplicationResponse update(UUID id, UpdateApplicationRequest request);
|
||||
ApplicationResponse findById(UUID id);
|
||||
Page<ApplicationResponse> findAll(Pageable pageable);
|
||||
Page<ApplicationResponse> search(ApplicationStatus status, UUID businessUnitId, String name, Pageable pageable);
|
||||
Page<ApplicationResponse> findByStatus(ApplicationStatus status, Pageable pageable);
|
||||
Page<ApplicationResponse> findByBusinessUnit(UUID businessUnitId, Pageable pageable);
|
||||
void delete(UUID id);
|
||||
ApplicationResponse updateStatus(UUID id, ApplicationStatus newStatus);
|
||||
```
|
||||
- [ ] Implement business logic:
|
||||
- Validate business unit exists on create/update
|
||||
- Validate end-of-support date is before end-of-life date
|
||||
- Throw exceptions for invalid states
|
||||
- Map entities to DTOs (consider using MapStruct or ModelMapper)
|
||||
|
||||
#### 7. Controller Layer
|
||||
- [ ] Create `ApplicationController` with endpoints:
|
||||
```java
|
||||
GET /api/applications - List all (with filters)
|
||||
GET /api/applications/search - Advanced search
|
||||
GET /api/applications/{id} - Get by ID
|
||||
POST /api/applications - Create new
|
||||
PUT /api/applications/{id} - Update
|
||||
PATCH /api/applications/{id}/status - Update status only
|
||||
DELETE /api/applications/{id} - Delete
|
||||
GET /api/applications/by-status/{status} - Filter by status
|
||||
GET /api/applications/by-business-unit/{businessUnitId} - Filter by BU
|
||||
```
|
||||
- [ ] Add query parameters for filtering:
|
||||
- `status`: Filter by status
|
||||
- `businessUnitId`: Filter by business unit
|
||||
- `name`: Search by name
|
||||
- `page`, `size`, `sort`: Pagination
|
||||
- [ ] Add validation annotations
|
||||
- [ ] Add Swagger/OpenAPI annotations
|
||||
- [ ] Add security: require authentication
|
||||
|
||||
#### 8. Testing
|
||||
- [ ] Unit tests for `ApplicationService`:
|
||||
- Test create application
|
||||
- Test create with invalid business unit (should fail)
|
||||
- Test update application
|
||||
- Test update status
|
||||
- Test search with various filters
|
||||
- Test validation (end-of-support before end-of-life)
|
||||
- [ ] Integration tests for `ApplicationController`:
|
||||
- Test full CRUD flow
|
||||
- Test filtering by status
|
||||
- Test filtering by business unit
|
||||
- Test search functionality
|
||||
- Test pagination and sorting
|
||||
- Test error cases (404, 400)
|
||||
- [ ] Test coverage > 80%
|
||||
|
||||
---
|
||||
|
||||
### Frontend Tasks
|
||||
|
||||
#### 1. Models
|
||||
- [ ] Create `application.model.ts`:
|
||||
```typescript
|
||||
export enum ApplicationStatus {
|
||||
IDEA = 'IDEA',
|
||||
IN_DEVELOPMENT = 'IN_DEVELOPMENT',
|
||||
IN_SERVICE = 'IN_SERVICE',
|
||||
MAINTENANCE = 'MAINTENANCE',
|
||||
DECOMMISSIONED = 'DECOMMISSIONED'
|
||||
}
|
||||
|
||||
export interface Application {
|
||||
id: string;
|
||||
name: string;
|
||||
description?: string;
|
||||
status: ApplicationStatus;
|
||||
businessUnit: { id: string; name: string };
|
||||
endOfLifeDate?: Date;
|
||||
endOfSupportDate?: Date;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
}
|
||||
|
||||
export interface CreateApplicationRequest {
|
||||
name: string;
|
||||
description?: string;
|
||||
status: ApplicationStatus;
|
||||
businessUnitId: string;
|
||||
endOfLifeDate?: Date;
|
||||
endOfSupportDate?: Date;
|
||||
}
|
||||
|
||||
export interface UpdateApplicationRequest {
|
||||
name?: string;
|
||||
description?: string;
|
||||
status?: ApplicationStatus;
|
||||
businessUnitId?: string;
|
||||
endOfLifeDate?: Date;
|
||||
endOfSupportDate?: Date;
|
||||
}
|
||||
```
|
||||
|
||||
#### 2. Service
|
||||
- [ ] Create `application.service.ts`:
|
||||
```typescript
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class ApplicationService {
|
||||
getApplications(filters?, page?, size?, sort?): Observable<Page<Application>>
|
||||
searchApplications(criteria): Observable<Page<Application>>
|
||||
getApplication(id): Observable<Application>
|
||||
createApplication(data): Observable<Application>
|
||||
updateApplication(id, data): Observable<Application>
|
||||
updateStatus(id, status): Observable<Application>
|
||||
deleteApplication(id): Observable<void>
|
||||
}
|
||||
```
|
||||
|
||||
#### 3. Components
|
||||
|
||||
##### ApplicationListComponent
|
||||
- [ ] Create component with template and styles
|
||||
- [ ] Features:
|
||||
- Table view with columns: Name, Status, Business Unit, End of Life, Actions
|
||||
- Status badge with color coding:
|
||||
- IDEA: blue
|
||||
- IN_DEVELOPMENT: yellow
|
||||
- IN_SERVICE: green
|
||||
- MAINTENANCE: orange
|
||||
- DECOMMISSIONED: gray
|
||||
- Filters:
|
||||
- Status dropdown (All, IDEA, IN_DEVELOPMENT, IN_SERVICE, MAINTENANCE, DECOMMISSIONED)
|
||||
- Business unit dropdown (All + list of BUs)
|
||||
- Search by name
|
||||
- Pagination controls (20 items per page)
|
||||
- Sort by name, status, created date
|
||||
- "Create New Application" button
|
||||
- Actions per row: View, Edit, Delete, Change Status
|
||||
- [ ] Implement logic:
|
||||
- Load applications on init
|
||||
- Apply filters reactively
|
||||
- Handle pagination and sorting
|
||||
- Handle search with debounce
|
||||
- Quick status change dropdown
|
||||
- Navigate to detail/form pages
|
||||
- Handle delete with confirmation
|
||||
|
||||
##### ApplicationDetailComponent
|
||||
- [ ] Create component with template and styles
|
||||
- [ ] Features:
|
||||
- Display all application details
|
||||
- Status badge (colored)
|
||||
- Business unit link (navigate to BU detail)
|
||||
- Show end-of-life and end-of-support dates (highlight if approaching)
|
||||
- "Edit" button
|
||||
- "Change Status" dropdown
|
||||
- "Delete" button
|
||||
- "Back to List" button
|
||||
- Tabs (for future: Versions, Deployments, Contacts)
|
||||
- [ ] Load application by ID from route params
|
||||
- [ ] Reload on status change
|
||||
|
||||
##### ApplicationFormComponent
|
||||
- [ ] Create component with template and styles
|
||||
- [ ] Reactive form with fields:
|
||||
- Name (required, max 255 chars)
|
||||
- Description (optional, textarea)
|
||||
- Status (required, dropdown)
|
||||
- Business Unit (required, dropdown - load from API)
|
||||
- End of Life Date (optional, date picker)
|
||||
- End of Support Date (optional, date picker)
|
||||
- [ ] Form validation:
|
||||
- Name required
|
||||
- Status required
|
||||
- Business unit required
|
||||
- End of support date must be before end of life date
|
||||
- Show validation errors
|
||||
- [ ] Support both create and edit modes
|
||||
- [ ] Handle form submission
|
||||
- [ ] "Cancel" button
|
||||
|
||||
#### 4. Shared Components
|
||||
- [ ] Create `StatusBadgeComponent`:
|
||||
- Input: status (ApplicationStatus)
|
||||
- Display colored badge based on status
|
||||
- Reusable across application views
|
||||
|
||||
#### 5. Routing
|
||||
- [ ] Add routes:
|
||||
```typescript
|
||||
{
|
||||
path: 'applications',
|
||||
canActivate: [AuthGuard],
|
||||
children: [
|
||||
{ path: '', component: ApplicationListComponent },
|
||||
{ path: 'new', component: ApplicationFormComponent },
|
||||
{ path: ':id', component: ApplicationDetailComponent },
|
||||
{ path: ':id/edit', component: ApplicationFormComponent }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
#### 6. Navigation
|
||||
- [ ] Add "Applications" link to header/sidebar (prominent position)
|
||||
|
||||
#### 7. Testing
|
||||
- [ ] Unit tests for `ApplicationService`
|
||||
- [ ] Component tests for `ApplicationListComponent`:
|
||||
- Test rendering
|
||||
- Test filters (status, business unit, search)
|
||||
- Test pagination
|
||||
- Test status change
|
||||
- [ ] Component tests for `ApplicationFormComponent`:
|
||||
- Test form validation
|
||||
- Test date validation (end-of-support before end-of-life)
|
||||
- Test create and edit modes
|
||||
- [ ] E2E tests:
|
||||
- Create application flow
|
||||
- Edit application flow
|
||||
- Change status flow
|
||||
- Filter and search flow
|
||||
- [ ] Test coverage > 70%
|
||||
|
||||
---
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
### Backend
|
||||
- [ ] Application can be created with all required fields
|
||||
- [ ] Application creation fails if business unit doesn't exist
|
||||
- [ ] Application can be updated (partial updates supported)
|
||||
- [ ] Application status can be updated independently
|
||||
- [ ] Application can be deleted
|
||||
- [ ] Applications can be listed with pagination
|
||||
- [ ] Applications can be filtered by status
|
||||
- [ ] Applications can be filtered by business unit
|
||||
- [ ] Applications can be searched by name
|
||||
- [ ] Advanced search combines multiple filters
|
||||
- [ ] End-of-support date validation (must be before end-of-life)
|
||||
- [ ] All endpoints authenticated
|
||||
- [ ] API documented in Swagger
|
||||
|
||||
### Frontend
|
||||
- [ ] User can view list of all applications
|
||||
- [ ] List shows application name, status, business unit
|
||||
- [ ] Status is displayed with colored badge
|
||||
- [ ] User can filter applications by status
|
||||
- [ ] User can filter applications by business unit
|
||||
- [ ] User can search applications by name
|
||||
- [ ] Filters work together (combined)
|
||||
- [ ] List supports pagination and sorting
|
||||
- [ ] User can create new application
|
||||
- [ ] Form validates all required fields
|
||||
- [ ] Form validates date logic (end-of-support before end-of-life)
|
||||
- [ ] User can view application details
|
||||
- [ ] User can edit existing application
|
||||
- [ ] User can change application status from list or detail view
|
||||
- [ ] User can delete application (with confirmation)
|
||||
- [ ] Approaching end-of-life dates are highlighted
|
||||
- [ ] Success/error notifications displayed
|
||||
- [ ] Navigation is intuitive
|
||||
|
||||
### Testing
|
||||
- [ ] Backend tests pass (>80% coverage)
|
||||
- [ ] Frontend tests pass (>70% coverage)
|
||||
- [ ] E2E tests pass
|
||||
|
||||
---
|
||||
|
||||
## Testing Scenarios
|
||||
|
||||
### Scenario 1: Create Application
|
||||
1. Navigate to applications list
|
||||
2. Click "Create New Application"
|
||||
3. Fill in form:
|
||||
- Name: "Customer Portal"
|
||||
- Description: "External customer-facing portal"
|
||||
- Status: IN_DEVELOPMENT
|
||||
- Business Unit: Select "Digital Services"
|
||||
- End of Support: 2028-12-31
|
||||
- End of Life: 2030-12-31
|
||||
4. Click "Save"
|
||||
5. Verify success notification
|
||||
6. Verify redirect to application list
|
||||
7. Verify new application appears with IN_DEVELOPMENT badge (yellow)
|
||||
|
||||
### Scenario 2: Filter Applications
|
||||
1. Navigate to applications list
|
||||
2. Select status filter: "IN_SERVICE"
|
||||
3. Verify only IN_SERVICE applications shown
|
||||
4. Select business unit filter: "Digital Services"
|
||||
5. Verify only IN_SERVICE applications from Digital Services shown
|
||||
6. Clear filters
|
||||
7. Verify all applications shown
|
||||
|
||||
### Scenario 3: Search Applications
|
||||
1. Navigate to applications list
|
||||
2. Enter search query: "portal"
|
||||
3. Wait for debounce
|
||||
4. Verify results contain only matching applications
|
||||
5. Clear search
|
||||
6. Verify all applications shown
|
||||
|
||||
### Scenario 4: Change Application Status
|
||||
1. Navigate to applications list
|
||||
2. Click "Change Status" dropdown on an application
|
||||
3. Select new status: "IN_SERVICE"
|
||||
4. Verify success notification
|
||||
5. Verify status badge updated to green
|
||||
6. Refresh page
|
||||
7. Verify status persisted
|
||||
|
||||
### Scenario 5: Edit Application
|
||||
1. Navigate to application detail page
|
||||
2. Click "Edit"
|
||||
3. Modify description and end-of-life date
|
||||
4. Click "Save"
|
||||
5. Verify success notification
|
||||
6. Verify changes reflected in detail view
|
||||
|
||||
### Scenario 6: Date Validation
|
||||
1. Navigate to create/edit application form
|
||||
2. Set End of Support: 2030-12-31
|
||||
3. Set End of Life: 2028-12-31 (before end-of-support)
|
||||
4. Attempt to save
|
||||
5. Verify validation error: "End of support must be before end of life"
|
||||
6. Correct dates
|
||||
7. Verify form can be saved
|
||||
|
||||
### Scenario 7: Delete Application
|
||||
1. Navigate to application detail page
|
||||
2. Click "Delete"
|
||||
3. Confirm deletion
|
||||
4. Verify success notification
|
||||
5. Verify redirect to application list
|
||||
6. Verify application removed from list
|
||||
|
||||
---
|
||||
|
||||
## 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 operations via UI
|
||||
- [ ] Demo conducted successfully
|
||||
- [ ] Code merged to main branch
|
||||
|
||||
---
|
||||
|
||||
## Technical Debt & Future Improvements
|
||||
|
||||
### Known Limitations
|
||||
- No application archiving (only hard delete)
|
||||
- No status change audit trail
|
||||
- No automated end-of-life notifications
|
||||
- No application tags/categories
|
||||
|
||||
### Future Enhancements
|
||||
- Implement soft delete with archiving
|
||||
- Add status change history/audit log
|
||||
- Add automated alerts for approaching end-of-life
|
||||
- Add tagging system for categorization
|
||||
- Add application relationships (depends on, integrates with)
|
||||
- Add bulk status updates
|
||||
- Add export to Excel/CSV
|
||||
|
||||
---
|
||||
|
||||
## Dependencies & Blockers
|
||||
|
||||
### Dependencies
|
||||
- Story 1 (Business Units) must be complete
|
||||
|
||||
### Potential Blockers
|
||||
- None identified
|
||||
|
||||
---
|
||||
|
||||
**Story Status**: Ready for Development
|
||||
**Story Created**: February 2026
|
||||
**Estimated Completion**: 5-7 days from start
|
||||
@@ -0,0 +1,151 @@
|
||||
# Story 3: Contact Management
|
||||
|
||||
## Story Overview
|
||||
|
||||
**As a** system user
|
||||
**I want** to manage contacts and their roles
|
||||
**So that** I can associate stakeholders with applications and business units
|
||||
|
||||
**Story Type**: Feature
|
||||
**Priority**: Medium
|
||||
**Estimated Effort**: 3-5 days
|
||||
**Dependencies**: Story 0 (Foundation)
|
||||
|
||||
---
|
||||
|
||||
## Business Value
|
||||
|
||||
Contacts represent stakeholders (Product Owners, Developers, etc.) and their roles. This enables:
|
||||
- Tracking who is responsible for what
|
||||
- Contact information management
|
||||
- Foundation for application stakeholder mapping (used in later stories)
|
||||
|
||||
---
|
||||
|
||||
## Scope
|
||||
|
||||
### In Scope
|
||||
✅ Contact role management (predefined roles)
|
||||
✅ Person management (individuals)
|
||||
✅ Contact-Person associations
|
||||
✅ Basic CRUD for all entities
|
||||
|
||||
### Out of Scope (Story 2, 6)
|
||||
❌ Application-Contact associations (added when Story 2 needs it)
|
||||
❌ Business Unit-Contact associations
|
||||
❌ SLA-Contact associations (Phase 2)
|
||||
|
||||
---
|
||||
|
||||
## Database Schema
|
||||
|
||||
```sql
|
||||
-- Contact Roles (predefined)
|
||||
CREATE TABLE contact_role (
|
||||
id UUID PRIMARY KEY,
|
||||
role_name VARCHAR(100) UNIQUE NOT NULL,
|
||||
description TEXT,
|
||||
created_at TIMESTAMP NOT NULL,
|
||||
updated_at TIMESTAMP NOT NULL
|
||||
);
|
||||
|
||||
-- Persons (individuals)
|
||||
CREATE TABLE person (
|
||||
id UUID PRIMARY KEY,
|
||||
first_name VARCHAR(100) NOT NULL,
|
||||
last_name VARCHAR(100) NOT NULL,
|
||||
email VARCHAR(255) UNIQUE NOT NULL,
|
||||
phone VARCHAR(50),
|
||||
created_at TIMESTAMP NOT NULL,
|
||||
updated_at TIMESTAMP NOT NULL
|
||||
);
|
||||
|
||||
-- Contacts (functional roles)
|
||||
CREATE TABLE contact (
|
||||
id UUID PRIMARY KEY,
|
||||
contact_role_id UUID NOT NULL REFERENCES contact_role(id),
|
||||
created_at TIMESTAMP NOT NULL,
|
||||
updated_at TIMESTAMP NOT NULL
|
||||
);
|
||||
|
||||
-- Contact-Person junction (many-to-many)
|
||||
CREATE TABLE contact_person (
|
||||
contact_id UUID NOT NULL REFERENCES contact(id) ON DELETE CASCADE,
|
||||
person_id UUID NOT NULL REFERENCES person(id) ON DELETE CASCADE,
|
||||
is_primary BOOLEAN NOT NULL DEFAULT false,
|
||||
PRIMARY KEY (contact_id, person_id)
|
||||
);
|
||||
|
||||
-- Indexes
|
||||
CREATE INDEX idx_person_email ON person(email);
|
||||
CREATE INDEX idx_contact_role ON contact(contact_role_id);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Key Endpoints
|
||||
|
||||
### Contact Roles
|
||||
- `GET /api/contact-roles` - List all roles
|
||||
- `POST /api/contact-roles` - Create role (admin only)
|
||||
|
||||
### Persons
|
||||
- `GET /api/persons` - List all persons
|
||||
- `GET /api/persons/{id}` - Get person details
|
||||
- `POST /api/persons` - Create person
|
||||
- `PUT /api/persons/{id}` - Update person
|
||||
- `DELETE /api/persons/{id}` - Delete person
|
||||
|
||||
### Contacts
|
||||
- `GET /api/contacts` - List all contacts
|
||||
- `GET /api/contacts/{id}` - Get contact with persons
|
||||
- `POST /api/contacts` - Create contact (with person IDs)
|
||||
- `PUT /api/contacts/{id}` - Update contact
|
||||
- `POST /api/contacts/{id}/persons/{personId}` - Add person to contact
|
||||
- `DELETE /api/contacts/{id}/persons/{personId}` - Remove person from contact
|
||||
- `PATCH /api/contacts/{id}/persons/{personId}/primary` - Set as primary
|
||||
|
||||
---
|
||||
|
||||
## Frontend Components
|
||||
|
||||
### PersonListComponent
|
||||
- Table: First Name, Last Name, Email, Phone, Actions
|
||||
- CRUD operations
|
||||
|
||||
### ContactRoleListComponent
|
||||
- Simple list of roles (mostly read-only for regular users)
|
||||
|
||||
### ContactFormComponent
|
||||
- Select contact role (dropdown)
|
||||
- Multi-select persons (with primary designation)
|
||||
- Add/remove persons dynamically
|
||||
|
||||
---
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
- [ ] Contact roles can be created and listed
|
||||
- [ ] Persons can be created with unique email
|
||||
- [ ] Contacts can be created with role and persons
|
||||
- [ ] One person per contact can be marked as primary
|
||||
- [ ] Person can be associated with multiple contacts
|
||||
- [ ] All CRUD operations work via UI
|
||||
- [ ] Email uniqueness enforced
|
||||
- [ ] Tests pass (>80% backend, >70% frontend)
|
||||
|
||||
---
|
||||
|
||||
## Testing Scenarios
|
||||
|
||||
1. **Create Person**: Add new person with unique email
|
||||
2. **Duplicate Email**: Attempt to create person with existing email (should fail)
|
||||
3. **Create Contact**: Create contact with role and multiple persons
|
||||
4. **Set Primary**: Mark one person as primary contact
|
||||
5. **Remove Person**: Remove person from contact
|
||||
6. **Delete Person**: Delete person (should remove from all contacts)
|
||||
|
||||
---
|
||||
|
||||
**Story Status**: Ready for Development
|
||||
**Estimated Completion**: 3-5 days
|
||||
@@ -0,0 +1,104 @@
|
||||
# Story 4: Environment Management (Enhancement)
|
||||
|
||||
## Story Overview
|
||||
|
||||
**As a** system administrator
|
||||
**I want** to enhance environment management
|
||||
**So that** I can better organize and categorize deployment targets
|
||||
|
||||
**Story Type**: Enhancement
|
||||
**Priority**: Medium
|
||||
**Estimated Effort**: 2-3 days
|
||||
**Dependencies**: Story 0 (Foundation - basic Environment CRUD exists)
|
||||
|
||||
---
|
||||
|
||||
## Business Value
|
||||
|
||||
Story 0 created basic Environment CRUD. This story enhances it with:
|
||||
- Better organization and categorization
|
||||
- Production environment safety controls
|
||||
- Criticality-based filtering and alerts
|
||||
- Foundation for environment-specific permissions
|
||||
|
||||
---
|
||||
|
||||
## Scope
|
||||
|
||||
### In Scope (Enhancements to Story 0)
|
||||
✅ Add environment categorization/tags
|
||||
✅ Add environment deactivation (soft delete)
|
||||
✅ Add production environment warnings
|
||||
✅ Add environment groups (e.g., "Production EU", "Development")
|
||||
✅ Enhanced search and filtering
|
||||
|
||||
### Out of Scope
|
||||
❌ Environment-specific user permissions (future)
|
||||
❌ Environment health monitoring (future)
|
||||
|
||||
---
|
||||
|
||||
## Database Migration
|
||||
|
||||
```sql
|
||||
-- Add new columns to existing environment table
|
||||
ALTER TABLE environment
|
||||
ADD COLUMN is_active BOOLEAN NOT NULL DEFAULT true,
|
||||
ADD COLUMN environment_group VARCHAR(100),
|
||||
ADD COLUMN tags VARCHAR(255);
|
||||
|
||||
-- Index for filtering
|
||||
CREATE INDEX idx_environment_active ON environment(is_active);
|
||||
CREATE INDEX idx_environment_group ON environment(environment_group);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Key Enhancements
|
||||
|
||||
### Backend
|
||||
- [ ] Add `isActive` field to Environment entity (soft delete)
|
||||
- [ ] Add `environmentGroup` field (e.g., "Production", "Non-Production")
|
||||
- [ ] Add `tags` field (comma-separated or JSON array)
|
||||
- [ ] Update `EnvironmentRepository` with new queries:
|
||||
- `findByIsActive(boolean)`
|
||||
- `findByEnvironmentGroup(String)`
|
||||
- `findByIsProductionAndIsActive(boolean, boolean)`
|
||||
- [ ] Add deactivate/reactivate methods to service
|
||||
- [ ] Update DTOs with new fields
|
||||
|
||||
### Frontend
|
||||
- [ ] Add "Active/Inactive" filter toggle
|
||||
- [ ] Add "Group" filter dropdown
|
||||
- [ ] Show warning dialog when creating/editing production environments
|
||||
- [ ] Show "Deactivate" instead of "Delete" (with reactivate option)
|
||||
- [ ] Add visual indicators for inactive environments (grayed out)
|
||||
- [ ] Add environment group badges
|
||||
|
||||
---
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
- [ ] Environments can be deactivated (soft delete)
|
||||
- [ ] Inactive environments are hidden by default
|
||||
- [ ] User can view inactive environments via filter
|
||||
- [ ] Inactive environments can be reactivated
|
||||
- [ ] Production environments show warning before modifications
|
||||
- [ ] Environments can be organized into groups
|
||||
- [ ] Environments can be tagged
|
||||
- [ ] Search includes tags and groups
|
||||
|
||||
---
|
||||
|
||||
## Testing Scenarios
|
||||
|
||||
1. **Deactivate Environment**: Deactivate an environment, verify it's hidden from default list
|
||||
2. **Reactivate Environment**: Reactivate an environment, verify it appears again
|
||||
3. **Production Warning**: Attempt to edit production environment, verify warning shown
|
||||
4. **Group Filtering**: Filter by environment group, verify correct results
|
||||
5. **Tag Search**: Search by tag, verify matching environments shown
|
||||
|
||||
---
|
||||
|
||||
**Story Status**: Ready for Development
|
||||
**Estimated Completion**: 2-3 days
|
||||
@@ -0,0 +1,175 @@
|
||||
# Story 5: Version Management
|
||||
|
||||
## Story Overview
|
||||
|
||||
**As a** application manager
|
||||
**I want** to track application versions
|
||||
**So that** I can manage releases and their lifecycle
|
||||
|
||||
**Story Type**: Feature (Core Domain)
|
||||
**Priority**: High
|
||||
**Estimated Effort**: 3-4 days
|
||||
**Dependencies**: Story 2 (Applications)
|
||||
|
||||
---
|
||||
|
||||
## Business Value
|
||||
|
||||
Versions represent application releases. This enables:
|
||||
- Tracking what versions exist for each application
|
||||
- Version lifecycle management (release date, end-of-life)
|
||||
- Foundation for deployment tracking (Story 6)
|
||||
- Link to external references (Git tags, JIRA releases)
|
||||
|
||||
---
|
||||
|
||||
## Scope
|
||||
|
||||
### In Scope
|
||||
✅ Version CRUD operations
|
||||
✅ Version-Application association
|
||||
✅ Version lifecycle (release date, end-of-life)
|
||||
✅ External reference tracking (Git, JIRA, etc.)
|
||||
✅ Version listing per application
|
||||
|
||||
### Out of Scope
|
||||
❌ Deployment tracking (Story 6)
|
||||
❌ Version comparison/diff
|
||||
❌ Automated version detection from CI/CD
|
||||
|
||||
---
|
||||
|
||||
## Database Schema
|
||||
|
||||
```sql
|
||||
CREATE TABLE version (
|
||||
id UUID PRIMARY KEY,
|
||||
application_id UUID NOT NULL REFERENCES application(id) ON DELETE CASCADE,
|
||||
version_identifier VARCHAR(100) NOT NULL, -- "1.2.3", "2024.Q1"
|
||||
external_reference VARCHAR(500), -- Git tag, JIRA link, etc.
|
||||
release_date DATE NOT NULL,
|
||||
end_of_life_date DATE,
|
||||
created_at TIMESTAMP NOT NULL,
|
||||
updated_at TIMESTAMP NOT NULL,
|
||||
UNIQUE(application_id, version_identifier)
|
||||
);
|
||||
|
||||
CREATE INDEX idx_version_application ON version(application_id);
|
||||
CREATE INDEX idx_version_release_date ON version(release_date);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Key Endpoints
|
||||
|
||||
- `GET /api/applications/{appId}/versions` - List versions for application
|
||||
- `GET /api/versions/{id}` - Get version details
|
||||
- `POST /api/applications/{appId}/versions` - Create version
|
||||
- `PUT /api/versions/{id}` - Update version
|
||||
- `DELETE /api/versions/{id}` - Delete version
|
||||
- `GET /api/versions/latest?applicationId={appId}` - Get latest version
|
||||
|
||||
---
|
||||
|
||||
## DTOs
|
||||
|
||||
```typescript
|
||||
export interface Version {
|
||||
id: string;
|
||||
applicationId: string;
|
||||
versionIdentifier: string; // "1.2.3"
|
||||
externalReference?: string; // "https://github.com/org/repo/releases/tag/v1.2.3"
|
||||
releaseDate: Date;
|
||||
endOfLifeDate?: Date;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
}
|
||||
|
||||
export interface CreateVersionRequest {
|
||||
versionIdentifier: string;
|
||||
externalReference?: string;
|
||||
releaseDate: Date;
|
||||
endOfLifeDate?: Date;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Frontend Components
|
||||
|
||||
### VersionListComponent (sub-component of ApplicationDetailComponent)
|
||||
- Displayed as tab in Application Detail view
|
||||
- Table: Version, Release Date, End of Life, External Reference, Actions
|
||||
- "Add New Version" button
|
||||
- Sort by release date (newest first)
|
||||
- Actions: Edit, Delete
|
||||
|
||||
### VersionFormComponent
|
||||
- Modal or inline form
|
||||
- Fields:
|
||||
- Version Identifier (required, must be unique per application)
|
||||
- External Reference (optional, URL)
|
||||
- Release Date (required, date picker)
|
||||
- End of Life Date (optional, must be after release date)
|
||||
- Validation:
|
||||
- Version identifier unique within application
|
||||
- Dates valid (EOL after release)
|
||||
|
||||
---
|
||||
|
||||
## Business Rules
|
||||
|
||||
1. **Unique Version**: Version identifier must be unique within an application
|
||||
2. **Date Logic**: End-of-life date (if set) must be after release date
|
||||
3. **Latest Version**: System tracks the version with the most recent release date as "latest"
|
||||
4. **Deletion**: Can only delete version if not deployed anywhere (checked in Story 6)
|
||||
|
||||
---
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
- [ ] Version can be created for an application
|
||||
- [ ] Version identifier must be unique within application
|
||||
- [ ] Duplicate version identifiers are rejected
|
||||
- [ ] Version release date is required
|
||||
- [ ] End-of-life date validation (must be after release)
|
||||
- [ ] Versions listed per application
|
||||
- [ ] Versions sorted by release date (newest first)
|
||||
- [ ] Latest version is identifiable
|
||||
- [ ] Version can be edited
|
||||
- [ ] Version can be deleted
|
||||
- [ ] External reference links are clickable
|
||||
- [ ] Tests pass (>80% backend, >70% frontend)
|
||||
|
||||
---
|
||||
|
||||
## Testing Scenarios
|
||||
|
||||
1. **Create Version**: Add version "1.0.0" to an application
|
||||
2. **Duplicate Version**: Attempt to create "1.0.0" again (should fail)
|
||||
3. **Multiple Versions**: Create versions 1.0.0, 1.1.0, 2.0.0, verify sorting
|
||||
4. **Latest Version**: Verify version with most recent release date marked as latest
|
||||
5. **Edit Version**: Update end-of-life date
|
||||
6. **Delete Version**: Delete version (if not deployed)
|
||||
7. **Date Validation**: Set EOL before release date (should fail)
|
||||
|
||||
---
|
||||
|
||||
## Integration with Application Detail
|
||||
|
||||
The Application Detail page (from Story 2) will be enhanced with a "Versions" tab:
|
||||
|
||||
```
|
||||
Application Detail
|
||||
├── Overview (existing)
|
||||
├── Versions (NEW)
|
||||
│ ├── Version List
|
||||
│ └── Add Version Button
|
||||
├── Deployments (Story 6)
|
||||
└── Contacts (Story 3)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**Story Status**: Ready for Development
|
||||
**Estimated Completion**: 3-4 days
|
||||
@@ -0,0 +1,293 @@
|
||||
# Story 6: Deployment Tracking
|
||||
|
||||
## Story Overview
|
||||
|
||||
**As a** application manager
|
||||
**I want** to record and track deployments
|
||||
**So that** I know which version is deployed in each environment
|
||||
|
||||
**Story Type**: Feature (Core Domain)
|
||||
**Priority**: Highest
|
||||
**Estimated Effort**: 5-7 days
|
||||
**Dependencies**: Story 2 (Applications), Story 4 (Environments), Story 5 (Versions)
|
||||
|
||||
---
|
||||
|
||||
## Business Value
|
||||
|
||||
Deployments are the core tracking mechanism. This enables:
|
||||
- Record which application version is in which environment
|
||||
- Complete deployment history (audit trail)
|
||||
- Current state visibility (what's in production right now)
|
||||
- Foundation for compliance and change tracking
|
||||
|
||||
---
|
||||
|
||||
## Scope
|
||||
|
||||
### In Scope
|
||||
✅ Deployment recording (application + version + environment)
|
||||
✅ Deployment history (immutable records)
|
||||
✅ Current deployment state query
|
||||
✅ Deployment metadata (who, when, notes)
|
||||
✅ Basic deployment listing and filtering
|
||||
|
||||
### Out of Scope
|
||||
❌ Automated deployment from CI/CD
|
||||
❌ Deployment approval workflows
|
||||
❌ Rollback functionality
|
||||
❌ Deployment health monitoring
|
||||
|
||||
---
|
||||
|
||||
## Database Schema
|
||||
|
||||
```sql
|
||||
CREATE TABLE deployment (
|
||||
id UUID PRIMARY KEY,
|
||||
application_id UUID NOT NULL REFERENCES application(id),
|
||||
version_id UUID NOT NULL REFERENCES version(id),
|
||||
environment_id UUID NOT NULL REFERENCES environment(id),
|
||||
deployment_date TIMESTAMP NOT NULL,
|
||||
deployed_by VARCHAR(255), -- Username or system identifier
|
||||
notes TEXT,
|
||||
created_at TIMESTAMP NOT NULL,
|
||||
CONSTRAINT fk_deployment_application FOREIGN KEY (application_id) REFERENCES application(id),
|
||||
CONSTRAINT fk_deployment_version FOREIGN KEY (version_id) REFERENCES version(id),
|
||||
CONSTRAINT fk_deployment_environment FOREIGN KEY (environment_id) REFERENCES environment(id),
|
||||
CONSTRAINT check_version_belongs_to_app CHECK (
|
||||
EXISTS (SELECT 1 FROM version WHERE id = version_id AND application_id = deployment.application_id)
|
||||
)
|
||||
);
|
||||
|
||||
-- Indexes for common queries
|
||||
CREATE INDEX idx_deployment_application ON deployment(application_id);
|
||||
CREATE INDEX idx_deployment_environment ON deployment(environment_id);
|
||||
CREATE INDEX idx_deployment_date ON deployment(deployment_date DESC);
|
||||
CREATE INDEX idx_deployment_app_env ON deployment(application_id, environment_id);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Key Business Logic
|
||||
|
||||
### Current Deployment State
|
||||
The "current" deployment for an application in an environment is defined as:
|
||||
**The deployment with the most recent `deployment_date` for that (application, environment) combination**
|
||||
|
||||
Query:
|
||||
```sql
|
||||
SELECT DISTINCT ON (application_id, environment_id) *
|
||||
FROM deployment
|
||||
WHERE application_id = ? AND environment_id = ?
|
||||
ORDER BY application_id, environment_id, deployment_date DESC;
|
||||
```
|
||||
|
||||
### Immutability
|
||||
Deployments are **immutable** once created. No updates or deletions allowed (audit requirement). Only soft-delete for admin cleanup.
|
||||
|
||||
---
|
||||
|
||||
## Key Endpoints
|
||||
|
||||
### Recording Deployments
|
||||
- `POST /api/deployments` - Record new deployment
|
||||
- Request: `{ applicationId, versionId, environmentId, deploymentDate, deployedBy?, notes? }`
|
||||
- Validates version belongs to application
|
||||
- Validates deployment date not in future
|
||||
|
||||
### Querying Deployments
|
||||
- `GET /api/deployments` - List all deployments (paginated, filtered)
|
||||
- Filters: `applicationId`, `environmentId`, `versionId`, `dateFrom`, `dateTo`
|
||||
- `GET /api/deployments/{id}` - Get deployment details
|
||||
- `GET /api/deployments/current` - Get current state across all environments
|
||||
- Query params: `applicationId?`, `environmentId?`
|
||||
- `GET /api/applications/{appId}/deployments` - Deployment history for application
|
||||
- `GET /api/applications/{appId}/deployments/current` - Current state per environment for app
|
||||
- `GET /api/environments/{envId}/deployments/current` - All current deployments in environment
|
||||
|
||||
---
|
||||
|
||||
## DTOs
|
||||
|
||||
```typescript
|
||||
export interface Deployment {
|
||||
id: string;
|
||||
application: { id: string; name: string };
|
||||
version: { id: string; versionIdentifier: string };
|
||||
environment: { id: string; name: string };
|
||||
deploymentDate: Date;
|
||||
deployedBy?: string;
|
||||
notes?: string;
|
||||
createdAt: Date;
|
||||
}
|
||||
|
||||
export interface RecordDeploymentRequest {
|
||||
applicationId: string;
|
||||
versionId: string;
|
||||
environmentId: string;
|
||||
deploymentDate: Date;
|
||||
deployedBy?: string;
|
||||
notes?: string;
|
||||
}
|
||||
|
||||
export interface CurrentDeploymentState {
|
||||
application: { id: string; name: string };
|
||||
environment: { id: string; name: string };
|
||||
version: { id: string; versionIdentifier: string };
|
||||
deploymentDate: Date;
|
||||
deployedBy?: string;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Frontend Components
|
||||
|
||||
### RecordDeploymentComponent
|
||||
- Form to record new deployment:
|
||||
- Application (dropdown or pre-selected from context)
|
||||
- Version (dropdown - load versions for selected application)
|
||||
- Environment (dropdown)
|
||||
- Deployment Date (datetime picker, default: now)
|
||||
- Deployed By (text input, default: current user)
|
||||
- Notes (textarea, optional)
|
||||
- Validation:
|
||||
- All required fields
|
||||
- Version belongs to selected application
|
||||
- Date not in future
|
||||
- Submit creates immutable deployment record
|
||||
|
||||
### DeploymentHistoryComponent (tab in ApplicationDetailComponent)
|
||||
- Timeline view of deployments for an application
|
||||
- Group by environment
|
||||
- Show: Version, Environment, Date, Deployed By
|
||||
- Sort: Most recent first
|
||||
- Filter: By environment, by date range
|
||||
|
||||
### CurrentDeploymentStateComponent
|
||||
- Dashboard view showing current state
|
||||
- Matrix: Applications (rows) × Environments (columns)
|
||||
- Each cell shows: Version number, deployment date
|
||||
- Color coding:
|
||||
- Green: Recently deployed (< 30 days)
|
||||
- Yellow: Older deployment (30-90 days)
|
||||
- Red: Very old (> 90 days)
|
||||
- Click cell to see deployment details
|
||||
- "Record Deployment" action per cell
|
||||
|
||||
### EnvironmentDeploymentsComponent (tab in Environment detail)
|
||||
- List all applications currently deployed in this environment
|
||||
- Columns: Application, Version, Deployment Date, Deployed By
|
||||
- Link to application detail
|
||||
|
||||
---
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
### Backend
|
||||
- [ ] Deployment can be recorded with valid data
|
||||
- [ ] Version must belong to the specified application
|
||||
- [ ] Deployment date cannot be in future
|
||||
- [ ] Deployments are immutable (no updates/deletes)
|
||||
- [ ] Current deployment state query returns correct version per environment
|
||||
- [ ] Deployment history is complete and ordered correctly
|
||||
- [ ] All endpoints authenticated
|
||||
- [ ] Tests pass (>80% coverage)
|
||||
|
||||
### Frontend
|
||||
- [ ] User can record new deployment
|
||||
- [ ] Form validates all fields
|
||||
- [ ] Version dropdown shows only versions for selected application
|
||||
- [ ] Deployment appears immediately in history
|
||||
- [ ] Current state dashboard shows accurate data
|
||||
- [ ] Timeline view shows deployment history
|
||||
- [ ] User can filter deployment history
|
||||
- [ ] Deployment date defaults to current time
|
||||
- [ ] Deployed by defaults to current user
|
||||
- [ ] Tests pass (>70% coverage)
|
||||
|
||||
---
|
||||
|
||||
## Testing Scenarios
|
||||
|
||||
### Scenario 1: Record Deployment
|
||||
1. Navigate to "Record Deployment"
|
||||
2. Select Application: "Customer Portal"
|
||||
3. Version dropdown loads versions for Customer Portal
|
||||
4. Select Version: "1.2.0"
|
||||
5. Select Environment: "PROD-EU"
|
||||
6. Deployment Date defaults to now
|
||||
7. Deployed By defaults to current user
|
||||
8. Add notes: "Hotfix for login issue"
|
||||
9. Submit
|
||||
10. Verify success notification
|
||||
11. Verify deployment appears in history
|
||||
|
||||
### Scenario 2: Invalid Version
|
||||
1. Attempt to record deployment
|
||||
2. Manually set versionId for different application
|
||||
3. Submit
|
||||
4. Verify error: "Version does not belong to selected application"
|
||||
|
||||
### Scenario 3: Future Date Validation
|
||||
1. Record deployment
|
||||
2. Set deployment date to tomorrow
|
||||
3. Submit
|
||||
4. Verify error: "Deployment date cannot be in future"
|
||||
|
||||
### Scenario 4: Current State Query
|
||||
1. Record multiple deployments for same app in different environments
|
||||
2. Navigate to current state dashboard
|
||||
3. Verify each environment shows the most recent deployment
|
||||
4. Record new deployment for same app/env
|
||||
5. Verify dashboard updates to show new deployment
|
||||
|
||||
### Scenario 5: Deployment History
|
||||
1. Navigate to Application Detail → Deployments tab
|
||||
2. Verify all deployments shown, grouped by environment
|
||||
3. Verify sorted by date (most recent first)
|
||||
4. Filter by environment
|
||||
5. Verify only deployments to that environment shown
|
||||
|
||||
### Scenario 6: Environment View
|
||||
1. Navigate to Environment Detail → Deployments tab
|
||||
2. Verify all applications deployed to this environment shown
|
||||
3. Verify versions and dates correct
|
||||
4. Click on application
|
||||
5. Verify navigates to application detail
|
||||
|
||||
---
|
||||
|
||||
## Integration Points
|
||||
|
||||
### Application Detail Enhancement
|
||||
Add "Deployments" tab showing:
|
||||
- Current deployment state (per environment)
|
||||
- Deployment history timeline
|
||||
- "Record New Deployment" button
|
||||
|
||||
### Environment Detail Enhancement
|
||||
Add "Deployments" tab showing:
|
||||
- All applications currently deployed
|
||||
- Quick record deployment action
|
||||
|
||||
### Dashboard (new)
|
||||
Create main dashboard showing:
|
||||
- Current deployment state matrix
|
||||
- Recent deployments (last 10)
|
||||
- Quick stats (total apps, total deployments this week)
|
||||
|
||||
---
|
||||
|
||||
## Performance Considerations
|
||||
|
||||
- [ ] Index on (application_id, environment_id, deployment_date) for current state queries
|
||||
- [ ] Pagination for deployment history (can grow large)
|
||||
- [ ] Consider caching current deployment state (refresh every 5 min)
|
||||
- [ ] Optimize DISTINCT ON query for PostgreSQL
|
||||
|
||||
---
|
||||
|
||||
**Story Status**: Ready for Development
|
||||
**Estimated Completion**: 5-7 days
|
||||
@@ -0,0 +1,404 @@
|
||||
# Story 7: Current State Dashboard & Advanced History
|
||||
|
||||
## Story Overview
|
||||
|
||||
**As a** application manager
|
||||
**I want** a comprehensive view of deployment state and history
|
||||
**So that** I can quickly understand what's deployed where and track changes over time
|
||||
|
||||
**Story Type**: Feature (UI/UX Enhancement)
|
||||
**Priority**: High
|
||||
**Estimated Effort**: 4-5 days
|
||||
**Dependencies**: Story 6 (Deployments)
|
||||
|
||||
---
|
||||
|
||||
## Business Value
|
||||
|
||||
This story enhances deployment visibility by providing:
|
||||
- Executive dashboard with at-a-glance deployment status
|
||||
- Advanced filtering and search capabilities
|
||||
- Visual deployment timeline
|
||||
- Deployment analytics and trends
|
||||
- Export capabilities for reporting
|
||||
|
||||
---
|
||||
|
||||
## Scope
|
||||
|
||||
### In Scope
|
||||
✅ Main deployment dashboard (matrix view)
|
||||
✅ Advanced filtering (multi-criteria)
|
||||
✅ Deployment timeline visualization
|
||||
✅ Quick stats and KPIs
|
||||
✅ Export to CSV/Excel
|
||||
✅ Deployment calendar view
|
||||
|
||||
### Out of Scope
|
||||
❌ Automated alerts/notifications (Phase 2)
|
||||
❌ Deployment approval workflows (Phase 2)
|
||||
❌ Integration with monitoring tools (Phase 2)
|
||||
❌ Predictive analytics (Phase 2)
|
||||
|
||||
---
|
||||
|
||||
## Components to Build
|
||||
|
||||
### 1. MainDashboardComponent (New Landing Page)
|
||||
|
||||
**Layout**:
|
||||
```
|
||||
┌─────────────────────────────────────────────────────┐
|
||||
│ Dashboard Header │
|
||||
│ ┌─────────────┬─────────────┬─────────────────────┐│
|
||||
│ │ Total Apps │ Deployments │ Prod Deployments ││
|
||||
│ │ 42 │ This Week │ This Month ││
|
||||
│ │ │ 18 │ 156 ││
|
||||
│ └─────────────┴─────────────┴─────────────────────┘│
|
||||
├─────────────────────────────────────────────────────┤
|
||||
│ Current Deployment State Matrix │
|
||||
│ │
|
||||
│ │ PROD-EU │ PROD-US │ INT │ TEST │ DEV │
|
||||
│ ────────┼─────────┼─────────┼──────┼──────┼────── │
|
||||
│ App1 │ v2.1.0 │ v2.1.0 │v2.2.0│v2.3.0│v3.0.0 │
|
||||
│ App2 │ v1.5.2 │ v1.5.2 │v1.6.0│v1.6.0│v1.6.1 │
|
||||
│ ... │
|
||||
├─────────────────────────────────────────────────────┤
|
||||
│ Recent Deployments (Last 10) │
|
||||
│ • Customer Portal v2.1.0 → PROD-EU (2 hours ago) │
|
||||
│ • Mobile App v3.2.1 → TEST (5 hours ago) │
|
||||
│ ... │
|
||||
└─────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**Features**:
|
||||
- [ ] KPI cards at top (total apps, deployments this week/month, production deployments)
|
||||
- [ ] Deployment matrix (applications × environments)
|
||||
- Cell shows version number and deployment date
|
||||
- Color coding by age (green < 30d, yellow 30-90d, red > 90d)
|
||||
- Click cell to see deployment details
|
||||
- Hover shows tooltip with full details
|
||||
- [ ] Recent deployments list (last 10, with "View All" link)
|
||||
- [ ] Filters:
|
||||
- By status (all, production only, non-production)
|
||||
- By business unit
|
||||
- By application
|
||||
- Date range
|
||||
|
||||
### 2. DeploymentHistoryComponent (Enhanced)
|
||||
|
||||
**Features**:
|
||||
- [ ] Timeline visualization
|
||||
- Vertical timeline showing deployments chronologically
|
||||
- Group by application or environment (toggle)
|
||||
- Show version transitions (v1.0 → v1.1 → v2.0)
|
||||
- [ ] Advanced filters:
|
||||
- Application (multi-select)
|
||||
- Environment (multi-select)
|
||||
- Version
|
||||
- Date range (from/to)
|
||||
- Deployed by (user)
|
||||
- [ ] Sorting options:
|
||||
- By date (asc/desc)
|
||||
- By application
|
||||
- By environment
|
||||
- [ ] Export functionality:
|
||||
- Export to CSV
|
||||
- Export to Excel
|
||||
- Include all filtered results
|
||||
|
||||
### 3. DeploymentCalendarComponent (New)
|
||||
|
||||
**Features**:
|
||||
- [ ] Calendar view of deployments
|
||||
- [ ] Each day shows number of deployments
|
||||
- [ ] Click day to see details
|
||||
- [ ] Color coding:
|
||||
- High activity days (>10 deployments) - red
|
||||
- Normal activity (3-10) - yellow
|
||||
- Low activity (1-2) - green
|
||||
- No deployments - gray
|
||||
- [ ] Filter by environment type (production/non-production)
|
||||
|
||||
### 4. DeploymentSearchComponent (New)
|
||||
|
||||
**Advanced Search Form**:
|
||||
- [ ] Multi-criteria search:
|
||||
- Application name (autocomplete)
|
||||
- Version identifier (text)
|
||||
- Environment name (multi-select)
|
||||
- Date range
|
||||
- Deployed by (autocomplete)
|
||||
- Notes/comments contain (text search)
|
||||
- [ ] Save search criteria as "favorite"
|
||||
- [ ] Share search URL (encode filters in URL params)
|
||||
- [ ] Results table with all deployment details
|
||||
- [ ] Export results
|
||||
|
||||
### 5. DeploymentStatsComponent (New)
|
||||
|
||||
**Analytics Dashboard**:
|
||||
- [ ] Deployment frequency chart
|
||||
- Bar chart: Deployments per day/week/month
|
||||
- Toggle time range (last 7 days, 30 days, 90 days)
|
||||
- [ ] Top deployed applications (pie chart)
|
||||
- [ ] Deployment by environment (bar chart)
|
||||
- [ ] Deployment trends:
|
||||
- Average deployments per week (with trend line)
|
||||
- Most active deployment days/times
|
||||
- [ ] Version distribution:
|
||||
- How many environments run each version
|
||||
- Identify outdated versions in production
|
||||
|
||||
---
|
||||
|
||||
## Backend Enhancements
|
||||
|
||||
### New Endpoints
|
||||
|
||||
```java
|
||||
// Statistics
|
||||
GET /api/deployments/stats/summary
|
||||
- Returns: { totalApps, totalDeployments, deploymentsThisWeek, deploymentsThisMonth, prodDeployments }
|
||||
|
||||
GET /api/deployments/stats/frequency?range={7|30|90}
|
||||
- Returns: Deployment count per day for specified range
|
||||
|
||||
GET /api/deployments/stats/by-environment
|
||||
- Returns: Deployment count per environment
|
||||
|
||||
GET /api/deployments/stats/by-application
|
||||
- Returns: Top 10 most deployed applications
|
||||
|
||||
GET /api/deployments/stats/version-distribution
|
||||
- Returns: Version counts across all environments
|
||||
|
||||
// Advanced Search
|
||||
GET /api/deployments/search
|
||||
- Query params: applicationName, versionId, environmentIds[], dateFrom, dateTo, deployedBy, notes
|
||||
- Returns: Paginated search results
|
||||
|
||||
// Export
|
||||
GET /api/deployments/export?format={csv|excel}&filters=...
|
||||
- Returns: File download with deployment data
|
||||
|
||||
// Calendar View
|
||||
GET /api/deployments/calendar?year={year}&month={month}
|
||||
- Returns: Deployment counts per day for the month
|
||||
```
|
||||
|
||||
### Service Layer
|
||||
|
||||
```java
|
||||
@Service
|
||||
public class DeploymentStatisticsService {
|
||||
DeploymentSummaryDto getSummaryStatistics();
|
||||
List<DeploymentFrequencyDto> getDeploymentFrequency(int days);
|
||||
List<EnvironmentDeploymentCountDto> getDeploymentsByEnvironment();
|
||||
List<ApplicationDeploymentCountDto> getTopDeployedApplications(int limit);
|
||||
Map<String, Integer> getVersionDistribution();
|
||||
}
|
||||
|
||||
@Service
|
||||
public class DeploymentExportService {
|
||||
byte[] exportToCsv(DeploymentSearchCriteria criteria);
|
||||
byte[] exportToExcel(DeploymentSearchCriteria criteria);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Frontend Services
|
||||
|
||||
```typescript
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class DeploymentStatisticsService {
|
||||
getSummary(): Observable<DeploymentSummary>
|
||||
getFrequency(days: number): Observable<DeploymentFrequency[]>
|
||||
getByEnvironment(): Observable<EnvironmentStats[]>
|
||||
getByApplication(): Observable<ApplicationStats[]>
|
||||
getVersionDistribution(): Observable<VersionDistribution>
|
||||
getCalendarData(year, month): Observable<CalendarData>
|
||||
}
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class DeploymentExportService {
|
||||
exportToCsv(filters: DeploymentFilters): Observable<Blob>
|
||||
exportToExcel(filters: DeploymentFilters): Observable<Blob>
|
||||
downloadFile(blob: Blob, filename: string): void
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Charting Library
|
||||
|
||||
Use **Chart.js** or **ng2-charts** (Angular wrapper) for visualizations:
|
||||
- Bar charts (deployment frequency, by environment)
|
||||
- Pie charts (top applications)
|
||||
- Line charts (trends over time)
|
||||
|
||||
---
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
### Dashboard
|
||||
- [ ] Dashboard shows KPI cards with accurate counts
|
||||
- [ ] Deployment matrix displays current state correctly
|
||||
- [ ] Matrix cells show version and date
|
||||
- [ ] Color coding reflects deployment age
|
||||
- [ ] Recent deployments list shows last 10
|
||||
- [ ] Dashboard loads in < 2 seconds
|
||||
|
||||
### History & Timeline
|
||||
- [ ] Timeline visualization shows deployment flow
|
||||
- [ ] Advanced filters work correctly (multi-select, date range)
|
||||
- [ ] Filters can be combined
|
||||
- [ ] Results update reactively when filters change
|
||||
- [ ] Timeline can be grouped by application or environment
|
||||
- [ ] Export to CSV works (all filtered results)
|
||||
- [ ] Export to Excel works with formatting
|
||||
|
||||
### Calendar View
|
||||
- [ ] Calendar shows deployment counts per day
|
||||
- [ ] Days are color-coded by activity level
|
||||
- [ ] Clicking day shows deployment details
|
||||
- [ ] Filter by production/non-production works
|
||||
|
||||
### Search
|
||||
- [ ] Advanced search supports all criteria
|
||||
- [ ] Autocomplete works for application and user fields
|
||||
- [ ] Search results are accurate and complete
|
||||
- [ ] Search URL can be shared (filters in URL)
|
||||
- [ ] Saved searches can be recalled
|
||||
|
||||
### Statistics
|
||||
- [ ] All statistics are accurate
|
||||
- [ ] Charts render correctly
|
||||
- [ ] Charts are responsive (resize with window)
|
||||
- [ ] Time range toggle works for frequency chart
|
||||
- [ ] Version distribution identifies outdated versions
|
||||
|
||||
### Performance
|
||||
- [ ] Dashboard loads < 2 seconds
|
||||
- [ ] Matrix supports 100+ applications without lag
|
||||
- [ ] Export handles 10,000+ deployments
|
||||
- [ ] Charts render smoothly
|
||||
|
||||
### Testing
|
||||
- [ ] Backend tests pass (>80% coverage)
|
||||
- [ ] Frontend tests pass (>70% coverage)
|
||||
- [ ] E2E tests cover all main workflows
|
||||
|
||||
---
|
||||
|
||||
## Testing Scenarios
|
||||
|
||||
### Scenario 1: Dashboard Overview
|
||||
1. Login and navigate to dashboard
|
||||
2. Verify KPIs show correct counts
|
||||
3. Verify deployment matrix displays
|
||||
4. Verify recent deployments list
|
||||
5. Click matrix cell
|
||||
6. Verify deployment details popup
|
||||
7. Filter by production only
|
||||
8. Verify matrix updates
|
||||
|
||||
### Scenario 2: Timeline Visualization
|
||||
1. Navigate to deployment history
|
||||
2. Switch to timeline view
|
||||
3. Verify chronological display
|
||||
4. Group by application
|
||||
5. Verify grouping works
|
||||
6. Group by environment
|
||||
7. Verify regrouping works
|
||||
8. Hover over deployment
|
||||
9. Verify tooltip shows details
|
||||
|
||||
### Scenario 3: Advanced Search
|
||||
1. Navigate to deployment search
|
||||
2. Select multiple applications
|
||||
3. Select date range
|
||||
4. Enter deployed by user
|
||||
5. Click search
|
||||
6. Verify results match criteria
|
||||
7. Export results to CSV
|
||||
8. Verify CSV contains filtered data
|
||||
|
||||
### Scenario 4: Calendar View
|
||||
1. Navigate to deployment calendar
|
||||
2. Verify current month displayed
|
||||
3. Verify days with deployments highlighted
|
||||
4. Click on high-activity day
|
||||
5. Verify deployment details shown
|
||||
6. Navigate to previous month
|
||||
7. Verify data updates
|
||||
|
||||
### Scenario 5: Statistics & Analytics
|
||||
1. Navigate to deployment stats
|
||||
2. Verify frequency chart displays
|
||||
3. Change time range to 90 days
|
||||
4. Verify chart updates
|
||||
5. View top applications chart
|
||||
6. Verify data accurate
|
||||
7. Check version distribution
|
||||
8. Verify outdated versions highlighted
|
||||
|
||||
### Scenario 6: Export Functionality
|
||||
1. Apply filters to deployment history
|
||||
2. Click "Export to CSV"
|
||||
3. Verify file downloads
|
||||
4. Open CSV
|
||||
5. Verify data matches filters
|
||||
6. Repeat with Excel format
|
||||
7. Verify Excel formatting
|
||||
|
||||
---
|
||||
|
||||
## Definition of Done
|
||||
|
||||
- [ ] All components implemented and functional
|
||||
- [ ] All acceptance criteria met
|
||||
- [ ] All tests passing (unit, integration, E2E)
|
||||
- [ ] Dashboard performance < 2 seconds
|
||||
- [ ] Export handles large datasets
|
||||
- [ ] Charts render correctly on all screen sizes
|
||||
- [ ] Code reviewed and approved
|
||||
- [ ] User documentation updated
|
||||
- [ ] Demo conducted successfully
|
||||
- [ ] Code merged to main branch
|
||||
|
||||
---
|
||||
|
||||
## Performance Optimization
|
||||
|
||||
### Backend
|
||||
- [ ] Add database indexes for statistics queries
|
||||
- [ ] Cache statistics (refresh every 5 minutes)
|
||||
- [ ] Optimize current state query (materialized view?)
|
||||
- [ ] Paginate export for very large datasets
|
||||
|
||||
### Frontend
|
||||
- [ ] Virtual scrolling for large deployment lists
|
||||
- [ ] Lazy load dashboard widgets
|
||||
- [ ] Debounce filter inputs
|
||||
- [ ] Cache chart data (avoid re-render on resize)
|
||||
- [ ] Use TrackBy for ngFor (performance)
|
||||
|
||||
---
|
||||
|
||||
## Future Enhancements (Phase 2)
|
||||
|
||||
- [ ] Real-time deployment tracking (WebSocket updates)
|
||||
- [ ] Deployment approval workflows
|
||||
- [ ] Automated deployment notifications
|
||||
- [ ] Integration with CI/CD pipelines
|
||||
- [ ] Deployment health status tracking
|
||||
- [ ] Predictive analytics (deployment patterns)
|
||||
- [ ] Custom dashboards (user-configurable)
|
||||
- [ ] Mobile app for deployment monitoring
|
||||
|
||||
---
|
||||
|
||||
**Story Status**: Ready for Development
|
||||
**Estimated Completion**: 4-5 days
|
||||
Reference in New Issue
Block a user