autocomit
This commit is contained in:
@@ -0,0 +1,173 @@
|
||||
# LDPv2 - MVP Overview
|
||||
|
||||
## Purpose
|
||||
This MVP documentation package contains a complete breakdown of the LDPv2 project into iterative development stories following a "Walking Skeleton + Vertical Slices" approach.
|
||||
|
||||
## MVP Scope
|
||||
|
||||
The Minimum Viable Product focuses on delivering the core value proposition:
|
||||
**"Manage applications, track their deployments across environments, and maintain deployment history"**
|
||||
|
||||
### What's IN the MVP
|
||||
✅ Application management with lifecycle status
|
||||
✅ Environment management (flexible, production-ready)
|
||||
✅ Version tracking
|
||||
✅ Deployment recording and history
|
||||
✅ Current deployment state queries
|
||||
✅ Basic contact management
|
||||
✅ Business unit management
|
||||
✅ User authentication (local, JWT-based)
|
||||
✅ Basic role-based access control
|
||||
|
||||
### What's OUT of the MVP (Phase 2+)
|
||||
❌ External dependencies tracking
|
||||
❌ Data usage agreements
|
||||
❌ SLA management
|
||||
❌ Technical documentation links
|
||||
❌ Advanced reporting and dashboards
|
||||
❌ OAuth integration
|
||||
❌ Notification system
|
||||
❌ Advanced search and filtering
|
||||
|
||||
## Development Approach
|
||||
|
||||
### Phase 0: Foundation (Walking Skeleton)
|
||||
Establish the technical foundation and development patterns that will be replicated across all features.
|
||||
|
||||
**Duration**: 2-3 weeks
|
||||
**Goal**: Working authentication + 1 complete CRUD example
|
||||
|
||||
### Phase 1: Core Domain (Vertical Slices)
|
||||
Deliver business value incrementally with complete end-to-end features.
|
||||
|
||||
**Duration**: 6-8 weeks
|
||||
**Goal**: Fully functional application and deployment tracking
|
||||
|
||||
### Phase 2: Enrichment (Future)
|
||||
Add secondary features based on user feedback and business priorities.
|
||||
|
||||
## Story Structure
|
||||
|
||||
Each story follows this structure:
|
||||
```
|
||||
Story X: [Business Title]
|
||||
├── Backend Development
|
||||
│ ├── Database migration (Liquibase)
|
||||
│ ├── JPA Entities
|
||||
│ ├── Repository layer
|
||||
│ ├── Service layer (business logic)
|
||||
│ ├── DTOs (request/response)
|
||||
│ ├── Controller (REST endpoints)
|
||||
│ └── Tests (unit + integration)
|
||||
├── Frontend Development
|
||||
│ ├── TypeScript models/interfaces
|
||||
│ ├── Angular service (HTTP client)
|
||||
│ ├── Components (list, detail, form)
|
||||
│ ├── Routing configuration
|
||||
│ └── Tests (unit + e2e)
|
||||
└── Acceptance Criteria
|
||||
└── Testable user scenarios
|
||||
```
|
||||
|
||||
## Story Dependencies
|
||||
|
||||
```
|
||||
Story 0 (Foundation)
|
||||
├── Story 1 (Business Units) - Independent
|
||||
├── Story 2 (Applications) - Depends on Story 1
|
||||
├── Story 3 (Contacts) - Independent
|
||||
└── Story 4 (Environments) - Independent
|
||||
├── Story 5 (Versions) - Depends on Story 2
|
||||
└── Story 6 (Deployments) - Depends on Stories 2, 4, 5
|
||||
└── Story 7 (Current State & History) - Depends on Story 6
|
||||
```
|
||||
|
||||
## File Structure
|
||||
|
||||
```
|
||||
ldpv2-mvp/
|
||||
├── 00-MVP-OVERVIEW.md (this file)
|
||||
├── 01-TECHNICAL-SETUP.md
|
||||
├── stories/
|
||||
│ ├── STORY-0-Foundation.md
|
||||
│ ├── STORY-1-Business-Units.md
|
||||
│ ├── STORY-2-Applications.md
|
||||
│ ├── STORY-3-Contacts.md
|
||||
│ ├── STORY-4-Environments.md
|
||||
│ ├── STORY-5-Versions.md
|
||||
│ ├── STORY-6-Deployments.md
|
||||
│ └── STORY-7-Current-State-History.md
|
||||
├── data-model/
|
||||
│ ├── complete-data-model.ts
|
||||
│ ├── mvp-entities-only.ts
|
||||
│ └── database-schema.sql
|
||||
└── api-specs/
|
||||
├── openapi-mvp.yaml
|
||||
└── endpoint-summary.md
|
||||
```
|
||||
|
||||
## Success Metrics
|
||||
|
||||
The MVP will be considered successful when:
|
||||
|
||||
1. **Functional Completeness**
|
||||
- All 8 stories are delivered and accepted
|
||||
- All acceptance criteria are met
|
||||
- Zero critical bugs
|
||||
|
||||
2. **Technical Quality**
|
||||
- Backend test coverage > 80%
|
||||
- Frontend test coverage > 70%
|
||||
- All APIs documented in Swagger
|
||||
- Code passes security audit
|
||||
|
||||
3. **User Satisfaction**
|
||||
- Users can perform core workflows without assistance
|
||||
- System performance meets requirements (<500ms API response)
|
||||
- Positive feedback from pilot users
|
||||
|
||||
4. **Business Value**
|
||||
- All applications are registered in the system
|
||||
- Deployment history is accurate and complete
|
||||
- Users prefer LDPv2 over previous tools/spreadsheets
|
||||
|
||||
## Timeline Estimate
|
||||
|
||||
| Phase | Duration | Stories |
|
||||
|-------|----------|---------|
|
||||
| Phase 0: Foundation | 2-3 weeks | Story 0 |
|
||||
| Phase 1: Core (Batch 1) | 3-4 weeks | Stories 1-4 |
|
||||
| Phase 1: Core (Batch 2) | 3-4 weeks | Stories 5-7 |
|
||||
| **Total MVP** | **8-11 weeks** | **8 stories** |
|
||||
|
||||
*Note: Timeline assumes 1 full-time developer or 2 developers working part-time*
|
||||
|
||||
## Risk Mitigation
|
||||
|
||||
### Technical Risks
|
||||
- **Database performance**: Addressed with indexing strategy in Story 0
|
||||
- **JWT security**: Implemented following best practices in Story 0
|
||||
- **Complex queries**: Deployment history queries optimized in Story 7
|
||||
|
||||
### Process Risks
|
||||
- **Scope creep**: Strict adherence to MVP scope, Phase 2 features documented separately
|
||||
- **Incomplete data**: Import tools and validation built into each entity story
|
||||
- **User adoption**: Regular demos after each story completion
|
||||
|
||||
## Next Steps
|
||||
|
||||
1. Review this MVP overview
|
||||
2. Read the Technical Setup guide
|
||||
3. Begin with Story 0 (Foundation)
|
||||
4. Follow stories in dependency order
|
||||
5. Demo and gather feedback after every 2 stories
|
||||
|
||||
## Contact & Feedback
|
||||
|
||||
For questions or suggestions about this MVP plan, please contact the project team.
|
||||
|
||||
---
|
||||
|
||||
**Document Version**: 1.0
|
||||
**Last Updated**: February 2026
|
||||
**Status**: Ready for Development
|
||||
@@ -0,0 +1,702 @@
|
||||
# LDPv2 - Technical Setup Guide
|
||||
|
||||
## Overview
|
||||
|
||||
This guide provides the technical foundation for the LDPv2 project, including technology stack details, project structure, and initial setup instructions.
|
||||
|
||||
## Technology Stack
|
||||
|
||||
### Backend
|
||||
- **Framework**: Spring Boot 3.2.x
|
||||
- **Language**: Java 17 or 21
|
||||
- **Security**: Spring Security 6.x with JWT
|
||||
- **Persistence**:
|
||||
- PostgreSQL 16
|
||||
- Hibernate 6.x (JPA)
|
||||
- HikariCP (connection pooling)
|
||||
- **Migration**: Liquibase 4.x
|
||||
- **Build Tool**: Maven 3.9.x
|
||||
- **Testing**:
|
||||
- JUnit 5
|
||||
- Mockito
|
||||
- Testcontainers (for integration tests)
|
||||
- REST Assured (for API tests)
|
||||
- **Documentation**: SpringDoc OpenAPI (Swagger)
|
||||
- **Validation**: Jakarta Bean Validation
|
||||
|
||||
### Frontend
|
||||
- **Framework**: Angular 18
|
||||
- **Language**: TypeScript 5.x
|
||||
- **UI Library**: Angular Material or PrimeNG (to be decided)
|
||||
- **HTTP Client**: Angular HttpClient
|
||||
- **State Management**: Service-based (or NgRx for complex state)
|
||||
- **Forms**: Reactive Forms
|
||||
- **Routing**: Angular Router
|
||||
- **Testing**:
|
||||
- Jasmine/Karma (unit tests)
|
||||
- Cypress or Playwright (E2E tests)
|
||||
- **Build Tool**: Angular CLI
|
||||
|
||||
### DevOps
|
||||
- **Containerization**: Docker
|
||||
- **Container Orchestration**: Docker Compose (dev), Kubernetes (prod)
|
||||
- **CI/CD**: Jenkins, GitLab CI, or GitHub Actions
|
||||
- **Version Control**: Git
|
||||
|
||||
## Project Structure
|
||||
|
||||
### Backend Structure
|
||||
```
|
||||
ldpv2-backend/
|
||||
├── src/
|
||||
│ ├── main/
|
||||
│ │ ├── java/
|
||||
│ │ │ └── com/ldpv2/
|
||||
│ │ │ ├── LdpV2Application.java
|
||||
│ │ │ ├── config/
|
||||
│ │ │ │ ├── SecurityConfig.java
|
||||
│ │ │ │ ├── JwtConfig.java
|
||||
│ │ │ │ └── OpenApiConfig.java
|
||||
│ │ │ ├── domain/
|
||||
│ │ │ │ ├── entity/
|
||||
│ │ │ │ │ ├── BaseEntity.java
|
||||
│ │ │ │ │ ├── Application.java
|
||||
│ │ │ │ │ ├── Environment.java
|
||||
│ │ │ │ │ └── ...
|
||||
│ │ │ │ └── enums/
|
||||
│ │ │ │ ├── ApplicationStatus.java
|
||||
│ │ │ │ └── ExternalDependencyType.java
|
||||
│ │ │ ├── repository/
|
||||
│ │ │ │ ├── ApplicationRepository.java
|
||||
│ │ │ │ ├── EnvironmentRepository.java
|
||||
│ │ │ │ └── ...
|
||||
│ │ │ ├── service/
|
||||
│ │ │ │ ├── ApplicationService.java
|
||||
│ │ │ │ ├── EnvironmentService.java
|
||||
│ │ │ │ └── ...
|
||||
│ │ │ ├── dto/
|
||||
│ │ │ │ ├── request/
|
||||
│ │ │ │ │ ├── CreateApplicationRequest.java
|
||||
│ │ │ │ │ └── ...
|
||||
│ │ │ │ └── response/
|
||||
│ │ │ │ ├── ApplicationResponse.java
|
||||
│ │ │ │ └── ...
|
||||
│ │ │ ├── controller/
|
||||
│ │ │ │ ├── ApplicationController.java
|
||||
│ │ │ │ ├── EnvironmentController.java
|
||||
│ │ │ │ └── ...
|
||||
│ │ │ ├── security/
|
||||
│ │ │ │ ├── JwtTokenProvider.java
|
||||
│ │ │ │ ├── JwtAuthenticationFilter.java
|
||||
│ │ │ │ └── UserDetailsServiceImpl.java
|
||||
│ │ │ └── exception/
|
||||
│ │ │ ├── GlobalExceptionHandler.java
|
||||
│ │ │ ├── ResourceNotFoundException.java
|
||||
│ │ │ └── ...
|
||||
│ │ └── resources/
|
||||
│ │ ├── application.yml
|
||||
│ │ ├── application-dev.yml
|
||||
│ │ ├── application-prod.yml
|
||||
│ │ └── db/
|
||||
│ │ └── changelog/
|
||||
│ │ ├── db.changelog-master.xml
|
||||
│ │ ├── v1.0/
|
||||
│ │ │ ├── 001-create-base-tables.xml
|
||||
│ │ │ ├── 002-create-application-tables.xml
|
||||
│ │ │ └── ...
|
||||
│ │ └── data/
|
||||
│ │ └── initial-data.xml
|
||||
│ └── test/
|
||||
│ └── java/
|
||||
│ └── com/ldpv2/
|
||||
│ ├── integration/
|
||||
│ │ ├── ApplicationIntegrationTest.java
|
||||
│ │ └── ...
|
||||
│ ├── service/
|
||||
│ │ ├── ApplicationServiceTest.java
|
||||
│ │ └── ...
|
||||
│ └── controller/
|
||||
│ ├── ApplicationControllerTest.java
|
||||
│ └── ...
|
||||
├── pom.xml
|
||||
├── Dockerfile
|
||||
└── docker-compose.yml
|
||||
```
|
||||
|
||||
### Frontend Structure
|
||||
```
|
||||
ldpv2-frontend/
|
||||
├── src/
|
||||
│ ├── app/
|
||||
│ │ ├── core/
|
||||
│ │ │ ├── auth/
|
||||
│ │ │ │ ├── auth.service.ts
|
||||
│ │ │ │ ├── auth.guard.ts
|
||||
│ │ │ │ ├── jwt.interceptor.ts
|
||||
│ │ │ │ └── login/
|
||||
│ │ │ │ ├── login.component.ts
|
||||
│ │ │ │ ├── login.component.html
|
||||
│ │ │ │ └── login.component.scss
|
||||
│ │ │ ├── services/
|
||||
│ │ │ │ ├── api.service.ts
|
||||
│ │ │ │ └── error-handler.service.ts
|
||||
│ │ │ └── interceptors/
|
||||
│ │ │ ├── jwt.interceptor.ts
|
||||
│ │ │ └── error.interceptor.ts
|
||||
│ │ ├── shared/
|
||||
│ │ │ ├── models/
|
||||
│ │ │ │ ├── application.model.ts
|
||||
│ │ │ │ ├── environment.model.ts
|
||||
│ │ │ │ └── ...
|
||||
│ │ │ ├── components/
|
||||
│ │ │ │ ├── header/
|
||||
│ │ │ │ ├── footer/
|
||||
│ │ │ │ └── loading-spinner/
|
||||
│ │ │ └── pipes/
|
||||
│ │ │ └── date-format.pipe.ts
|
||||
│ │ ├── features/
|
||||
│ │ │ ├── applications/
|
||||
│ │ │ │ ├── application.service.ts
|
||||
│ │ │ │ ├── application-list/
|
||||
│ │ │ │ │ ├── application-list.component.ts
|
||||
│ │ │ │ │ ├── application-list.component.html
|
||||
│ │ │ │ │ └── application-list.component.scss
|
||||
│ │ │ │ ├── application-detail/
|
||||
│ │ │ │ └── application-form/
|
||||
│ │ │ ├── environments/
|
||||
│ │ │ │ ├── environment.service.ts
|
||||
│ │ │ │ └── ...
|
||||
│ │ │ ├── deployments/
|
||||
│ │ │ └── business-units/
|
||||
│ │ ├── app.component.ts
|
||||
│ │ ├── app.component.html
|
||||
│ │ ├── app.routes.ts
|
||||
│ │ └── app.config.ts
|
||||
│ ├── assets/
|
||||
│ │ ├── images/
|
||||
│ │ └── i18n/
|
||||
│ ├── environments/
|
||||
│ │ ├── environment.ts
|
||||
│ │ └── environment.prod.ts
|
||||
│ ├── styles.scss
|
||||
│ └── index.html
|
||||
├── angular.json
|
||||
├── package.json
|
||||
├── tsconfig.json
|
||||
└── Dockerfile
|
||||
```
|
||||
|
||||
## Initial Setup
|
||||
|
||||
### Prerequisites
|
||||
- JDK 17 or 21
|
||||
- Node.js 18+ and npm
|
||||
- Docker and Docker Compose
|
||||
- PostgreSQL 16 (or use Docker)
|
||||
- Git
|
||||
- IDE (IntelliJ IDEA, VS Code, or similar)
|
||||
|
||||
### Backend Setup
|
||||
|
||||
#### 1. Create Spring Boot Project
|
||||
```bash
|
||||
# Using Spring Initializr or
|
||||
# Download from https://start.spring.io with:
|
||||
# - Spring Boot 3.2.x
|
||||
# - Dependencies: Web, Security, JPA, PostgreSQL, Liquibase, Validation
|
||||
```
|
||||
|
||||
#### 2. Configure application.yml
|
||||
```yaml
|
||||
spring:
|
||||
application:
|
||||
name: ldpv2-backend
|
||||
|
||||
datasource:
|
||||
url: jdbc:postgresql://localhost:5432/ldpv2
|
||||
username: ldpv2_user
|
||||
password: ldpv2_password
|
||||
driver-class-name: org.postgresql.Driver
|
||||
hikari:
|
||||
maximum-pool-size: 10
|
||||
minimum-idle: 5
|
||||
|
||||
jpa:
|
||||
hibernate:
|
||||
ddl-auto: validate # Let Liquibase handle schema
|
||||
show-sql: true
|
||||
properties:
|
||||
hibernate:
|
||||
format_sql: true
|
||||
dialect: org.hibernate.dialect.PostgreSQLDialect
|
||||
|
||||
liquibase:
|
||||
change-log: classpath:db/changelog/db.changelog-master.xml
|
||||
enabled: true
|
||||
|
||||
jwt:
|
||||
secret: ${JWT_SECRET:your-secret-key-change-in-production}
|
||||
expiration: 3600000 # 1 hour in milliseconds
|
||||
|
||||
server:
|
||||
port: 8080
|
||||
servlet:
|
||||
context-path: /api
|
||||
|
||||
logging:
|
||||
level:
|
||||
com.ldpv2: DEBUG
|
||||
org.springframework.security: DEBUG
|
||||
```
|
||||
|
||||
#### 3. Docker Compose for Development
|
||||
```yaml
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:16-alpine
|
||||
container_name: ldpv2-postgres
|
||||
environment:
|
||||
POSTGRES_DB: ldpv2
|
||||
POSTGRES_USER: ldpv2_user
|
||||
POSTGRES_PASSWORD: ldpv2_password
|
||||
ports:
|
||||
- "5432:5432"
|
||||
volumes:
|
||||
- postgres_data:/var/lib/postgresql/data
|
||||
networks:
|
||||
- ldpv2-network
|
||||
|
||||
backend:
|
||||
build: ./ldpv2-backend
|
||||
container_name: ldpv2-backend
|
||||
depends_on:
|
||||
- postgres
|
||||
environment:
|
||||
SPRING_DATASOURCE_URL: jdbc:postgresql://postgres:5432/ldpv2
|
||||
SPRING_DATASOURCE_USERNAME: ldpv2_user
|
||||
SPRING_DATASOURCE_PASSWORD: ldpv2_password
|
||||
JWT_SECRET: development-secret-key
|
||||
ports:
|
||||
- "8080:8080"
|
||||
networks:
|
||||
- ldpv2-network
|
||||
|
||||
volumes:
|
||||
postgres_data:
|
||||
|
||||
networks:
|
||||
ldpv2-network:
|
||||
driver: bridge
|
||||
```
|
||||
|
||||
### Frontend Setup
|
||||
|
||||
#### 1. Create Angular Project
|
||||
```bash
|
||||
npm install -g @angular/cli@18
|
||||
ng new ldpv2-frontend
|
||||
cd ldpv2-frontend
|
||||
```
|
||||
|
||||
#### 2. Install Dependencies
|
||||
```bash
|
||||
# Angular Material (or PrimeNG)
|
||||
ng add @angular/material
|
||||
|
||||
# Additional dependencies
|
||||
npm install --save \
|
||||
@angular/common \
|
||||
@angular/forms \
|
||||
rxjs
|
||||
```
|
||||
|
||||
#### 3. Configure Environment
|
||||
```typescript
|
||||
// src/environments/environment.ts
|
||||
export const environment = {
|
||||
production: false,
|
||||
apiUrl: 'http://localhost:8080/api'
|
||||
};
|
||||
|
||||
// src/environments/environment.prod.ts
|
||||
export const environment = {
|
||||
production: true,
|
||||
apiUrl: '/api'
|
||||
};
|
||||
```
|
||||
|
||||
#### 4. Proxy Configuration for Development
|
||||
```json
|
||||
// proxy.conf.json
|
||||
{
|
||||
"/api": {
|
||||
"target": "http://localhost:8080",
|
||||
"secure": false,
|
||||
"changeOrigin": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Update `angular.json`:
|
||||
```json
|
||||
"serve": {
|
||||
"builder": "@angular-devkit/build-angular:dev-server",
|
||||
"options": {
|
||||
"proxyConfig": "proxy.conf.json"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Database Schema Management
|
||||
|
||||
### Liquibase Changelog Structure
|
||||
```xml
|
||||
<!-- db.changelog-master.xml -->
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<databaseChangeLog
|
||||
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
|
||||
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd">
|
||||
|
||||
<include file="db/changelog/v1.0/001-create-base-tables.xml"/>
|
||||
<include file="db/changelog/v1.0/002-create-application-tables.xml"/>
|
||||
<include file="db/changelog/v1.0/003-create-deployment-tables.xml"/>
|
||||
<!-- Add more as stories are developed -->
|
||||
|
||||
</databaseChangeLog>
|
||||
```
|
||||
|
||||
### Example Migration File
|
||||
```xml
|
||||
<!-- 001-create-base-tables.xml -->
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<databaseChangeLog
|
||||
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
|
||||
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd">
|
||||
|
||||
<changeSet id="001-create-base-entities" author="ldpv2-team">
|
||||
|
||||
<!-- Enable UUID extension -->
|
||||
<sql>CREATE EXTENSION IF NOT EXISTS "uuid-ossp";</sql>
|
||||
|
||||
<!-- Create Business Unit table -->
|
||||
<createTable tableName="business_unit">
|
||||
<column name="id" type="UUID" defaultValueComputed="uuid_generate_v4()">
|
||||
<constraints primaryKey="true" nullable="false"/>
|
||||
</column>
|
||||
<column name="name" type="VARCHAR(255)">
|
||||
<constraints nullable="false" unique="true"/>
|
||||
</column>
|
||||
<column name="created_at" type="TIMESTAMP" defaultValueComputed="CURRENT_TIMESTAMP">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="updated_at" type="TIMESTAMP" defaultValueComputed="CURRENT_TIMESTAMP">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
</createTable>
|
||||
|
||||
<!-- Create Environment table -->
|
||||
<createTable tableName="environment">
|
||||
<column name="id" type="UUID" defaultValueComputed="uuid_generate_v4()">
|
||||
<constraints primaryKey="true" nullable="false"/>
|
||||
</column>
|
||||
<column name="name" type="VARCHAR(100)">
|
||||
<constraints nullable="false" unique="true"/>
|
||||
</column>
|
||||
<column name="description" type="TEXT"/>
|
||||
<column name="is_production" type="BOOLEAN" defaultValueBoolean="false">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="criticality_level" type="INTEGER"/>
|
||||
<column name="created_at" type="TIMESTAMP" defaultValueComputed="CURRENT_TIMESTAMP">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="updated_at" type="TIMESTAMP" defaultValueComputed="CURRENT_TIMESTAMP">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
</createTable>
|
||||
|
||||
<!-- Indexes -->
|
||||
<createIndex tableName="environment" indexName="idx_env_is_production">
|
||||
<column name="is_production"/>
|
||||
</createIndex>
|
||||
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
||||
```
|
||||
|
||||
## Security Configuration
|
||||
|
||||
### JWT Token Provider Example
|
||||
```java
|
||||
@Component
|
||||
public class JwtTokenProvider {
|
||||
|
||||
@Value("${jwt.secret}")
|
||||
private String jwtSecret;
|
||||
|
||||
@Value("${jwt.expiration}")
|
||||
private long jwtExpiration;
|
||||
|
||||
public String generateToken(Authentication authentication) {
|
||||
UserDetails userDetails = (UserDetails) authentication.getPrincipal();
|
||||
Date now = new Date();
|
||||
Date expiryDate = new Date(now.getTime() + jwtExpiration);
|
||||
|
||||
return Jwts.builder()
|
||||
.setSubject(userDetails.getUsername())
|
||||
.setIssuedAt(now)
|
||||
.setExpiration(expiryDate)
|
||||
.signWith(SignatureAlgorithm.HS512, jwtSecret)
|
||||
.compact();
|
||||
}
|
||||
|
||||
public String getUsernameFromToken(String token) {
|
||||
Claims claims = Jwts.parser()
|
||||
.setSigningKey(jwtSecret)
|
||||
.parseClaimsJws(token)
|
||||
.getBody();
|
||||
return claims.getSubject();
|
||||
}
|
||||
|
||||
public boolean validateToken(String token) {
|
||||
try {
|
||||
Jwts.parser().setSigningKey(jwtSecret).parseClaimsJws(token);
|
||||
return true;
|
||||
} catch (SignatureException | MalformedJwtException | ExpiredJwtException |
|
||||
UnsupportedJwtException | IllegalArgumentException ex) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Security Configuration Example
|
||||
```java
|
||||
@Configuration
|
||||
@EnableWebSecurity
|
||||
@EnableMethodSecurity
|
||||
public class SecurityConfig {
|
||||
|
||||
@Bean
|
||||
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
|
||||
http
|
||||
.csrf(csrf -> csrf.disable())
|
||||
.cors(cors -> cors.configurationSource(corsConfigurationSource()))
|
||||
.sessionManagement(session ->
|
||||
session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
|
||||
.authorizeHttpRequests(auth -> auth
|
||||
.requestMatchers("/api/auth/**").permitAll()
|
||||
.requestMatchers("/api/public/**").permitAll()
|
||||
.requestMatchers("/swagger-ui/**", "/v3/api-docs/**").permitAll()
|
||||
.anyRequest().authenticated()
|
||||
)
|
||||
.addFilterBefore(jwtAuthenticationFilter(),
|
||||
UsernamePasswordAuthenticationFilter.class);
|
||||
|
||||
return http.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public CorsConfigurationSource corsConfigurationSource() {
|
||||
CorsConfiguration configuration = new CorsConfiguration();
|
||||
configuration.setAllowedOrigins(Arrays.asList("http://localhost:4200"));
|
||||
configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS"));
|
||||
configuration.setAllowedHeaders(Arrays.asList("*"));
|
||||
configuration.setAllowCredentials(true);
|
||||
|
||||
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
|
||||
source.registerCorsConfiguration("/**", configuration);
|
||||
return source;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public PasswordEncoder passwordEncoder() {
|
||||
return new BCryptPasswordEncoder();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## API Documentation (OpenAPI/Swagger)
|
||||
|
||||
### Configuration
|
||||
```java
|
||||
@Configuration
|
||||
public class OpenApiConfig {
|
||||
|
||||
@Bean
|
||||
public OpenAPI ldpV2OpenAPI() {
|
||||
return new OpenAPI()
|
||||
.info(new Info()
|
||||
.title("LDPv2 API")
|
||||
.description("Lifecycle Data Platform v2 - Application Management API")
|
||||
.version("1.0.0")
|
||||
.contact(new Contact()
|
||||
.name("LDPv2 Team")
|
||||
.email("team@ldpv2.com"))
|
||||
.license(new License()
|
||||
.name("Proprietary")
|
||||
.url("https://ldpv2.com/license")))
|
||||
.addSecurityItem(new SecurityRequirement().addList("bearerAuth"))
|
||||
.components(new Components()
|
||||
.addSecuritySchemes("bearerAuth",
|
||||
new SecurityScheme()
|
||||
.type(SecurityScheme.Type.HTTP)
|
||||
.scheme("bearer")
|
||||
.bearerFormat("JWT")));
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Access Swagger UI at: `http://localhost:8080/swagger-ui/index.html`
|
||||
|
||||
## Development Workflow
|
||||
|
||||
### Backend Development Cycle
|
||||
1. Create Liquibase migration
|
||||
2. Run migration: `mvn liquibase:update`
|
||||
3. Generate JPA entities
|
||||
4. Create repository interfaces
|
||||
5. Implement service layer
|
||||
6. Create DTOs
|
||||
7. Implement controller
|
||||
8. Write tests
|
||||
9. Document API with Swagger annotations
|
||||
10. Commit and push
|
||||
|
||||
### Frontend Development Cycle
|
||||
1. Create TypeScript models
|
||||
2. Implement Angular service
|
||||
3. Create components (list, detail, form)
|
||||
4. Add routing
|
||||
5. Style with CSS/SCSS
|
||||
6. Write tests
|
||||
7. Commit and push
|
||||
|
||||
## Testing Strategy
|
||||
|
||||
### Backend Testing
|
||||
```java
|
||||
// Unit Test Example
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class ApplicationServiceTest {
|
||||
|
||||
@Mock
|
||||
private ApplicationRepository applicationRepository;
|
||||
|
||||
@InjectMocks
|
||||
private ApplicationService applicationService;
|
||||
|
||||
@Test
|
||||
void shouldCreateApplication() {
|
||||
// Test implementation
|
||||
}
|
||||
}
|
||||
|
||||
// Integration Test Example with Testcontainers
|
||||
@SpringBootTest
|
||||
@Testcontainers
|
||||
class ApplicationIntegrationTest {
|
||||
|
||||
@Container
|
||||
static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:16-alpine");
|
||||
|
||||
@DynamicPropertySource
|
||||
static void configureProperties(DynamicPropertyRegistry registry) {
|
||||
registry.add("spring.datasource.url", postgres::getJdbcUrl);
|
||||
registry.add("spring.datasource.username", postgres::getUsername);
|
||||
registry.add("spring.datasource.password", postgres::getPassword);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldSaveAndRetrieveApplication() {
|
||||
// Test implementation
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Frontend Testing
|
||||
```typescript
|
||||
// Component Unit Test
|
||||
describe('ApplicationListComponent', () => {
|
||||
let component: ApplicationListComponent;
|
||||
let fixture: ComponentFixture<ApplicationListComponent>;
|
||||
let mockApplicationService: jasmine.SpyObj<ApplicationService>;
|
||||
|
||||
beforeEach(async () => {
|
||||
const spy = jasmine.createSpyObj('ApplicationService', ['getApplications']);
|
||||
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [ApplicationListComponent],
|
||||
providers: [
|
||||
{ provide: ApplicationService, useValue: spy }
|
||||
]
|
||||
}).compileComponents();
|
||||
|
||||
mockApplicationService = TestBed.inject(ApplicationService) as jasmine.SpyObj<ApplicationService>;
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
## Running the Application
|
||||
|
||||
### Development Mode
|
||||
|
||||
#### Backend
|
||||
```bash
|
||||
# Using Maven
|
||||
mvn spring-boot:run
|
||||
|
||||
# Using Docker Compose
|
||||
docker-compose up
|
||||
```
|
||||
|
||||
#### Frontend
|
||||
```bash
|
||||
# Development server
|
||||
ng serve
|
||||
|
||||
# With proxy
|
||||
ng serve --proxy-config proxy.conf.json
|
||||
|
||||
# Access at http://localhost:4200
|
||||
```
|
||||
|
||||
### Production Build
|
||||
|
||||
#### Backend
|
||||
```bash
|
||||
mvn clean package
|
||||
java -jar target/ldpv2-backend-1.0.0.jar
|
||||
```
|
||||
|
||||
#### Frontend
|
||||
```bash
|
||||
ng build --configuration production
|
||||
# Output in dist/ directory
|
||||
```
|
||||
|
||||
## Next Steps
|
||||
|
||||
After completing this technical setup:
|
||||
1. Proceed to Story 0 (Foundation) to build the Walking Skeleton
|
||||
2. Follow the story sequence for iterative development
|
||||
3. Maintain test coverage throughout
|
||||
4. Document APIs as you build
|
||||
5. Commit frequently with meaningful messages
|
||||
|
||||
---
|
||||
|
||||
**Document Version**: 1.0
|
||||
**Last Updated**: February 2026
|
||||
**Status**: Ready for Development
|
||||
+819
@@ -0,0 +1,819 @@
|
||||
# LDPv2 - Requirements Analysis Document
|
||||
|
||||
## 1. Executive Summary
|
||||
|
||||
LDPv2 (Lifecycle Data Platform version 2) is a comprehensive application lifecycle management tool designed to manage and document all applications within a business unit. It serves as a central repository for application information, tracking deployments, dependencies, SLAs, and stakeholder relationships throughout the complete application lifecycle.
|
||||
|
||||
## 2. Purpose and Scope
|
||||
|
||||
### 2.1 Primary Objectives
|
||||
|
||||
- Provide a centralized documentation platform for all managed applications
|
||||
- Track application lifecycle from ideation to decommissioning
|
||||
- Manage deployment history across multiple environments
|
||||
- Document and monitor external dependencies and data usage agreements
|
||||
- Maintain SLA definitions and compliance tracking
|
||||
- Facilitate stakeholder communication and responsibility mapping
|
||||
|
||||
### 2.2 Target Users
|
||||
|
||||
- Business Unit Directors and Program Managers
|
||||
- Application Product Owners
|
||||
- Development Teams
|
||||
- Infrastructure and Operations Teams
|
||||
- Compliance and Data Governance Officers
|
||||
|
||||
## 3. Technical Architecture
|
||||
|
||||
### 3.1 Technology Stack
|
||||
|
||||
#### 3.1.1 Backend
|
||||
|
||||
- **Framework**: Spring Boot 3.x
|
||||
- **Security**: Spring Security with JWT-based authentication
|
||||
- **Authentication Strategy**:
|
||||
- Initial implementation: Local authentication (username/password)
|
||||
- Future evolution: OAuth 2.0 / OpenID Connect integration
|
||||
- **Authorization**: Role-based access control (RBAC) with environment-specific permissions
|
||||
- **Persistence**: PostgreSQL 16
|
||||
- **ORM**: Hibernate 6.x (JPA implementation)
|
||||
- **API Style**: RESTful API with JSON payloads
|
||||
|
||||
#### 3.1.2 Frontend
|
||||
|
||||
- **Framework**: Angular 18
|
||||
- **Authentication**: JWT token-based authentication
|
||||
- **HTTP Client**: Angular HttpClient with interceptors for token management
|
||||
- **State Management**: To be determined (NgRx, Signals, or service-based)
|
||||
- **UI Components**: To be determined (Angular Material, PrimeNG, or custom)
|
||||
|
||||
#### 3.1.3 Database
|
||||
|
||||
- **RDBMS**: PostgreSQL 16
|
||||
- **Schema Management**: Liquibase or Flyway for database migrations
|
||||
- **Connection Pooling**: HikariCP (Spring Boot default)
|
||||
|
||||
### 3.2 Security Architecture
|
||||
|
||||
#### 3.2.1 Authentication Flow
|
||||
|
||||
1. User submits credentials to `/api/auth/login`
|
||||
2. Backend validates credentials against database
|
||||
3. Upon successful authentication, JWT token is generated and returned
|
||||
4. Frontend stores JWT token (localStorage or sessionStorage)
|
||||
5. Subsequent requests include JWT token in Authorization header
|
||||
6. Backend validates token on each request via Spring Security filters
|
||||
|
||||
#### 3.2.2 Authorization Model
|
||||
|
||||
- **Environment-Based Roles**: Users can have different permissions per environment
|
||||
- Example: User may have READ access to PROD but WRITE access to DEV
|
||||
- **Role Hierarchy**: To be defined (e.g., ADMIN > MANAGER > USER > VIEWER)
|
||||
- **Resource-Level Permissions**: Fine-grained access control on applications and business units
|
||||
|
||||
#### 3.2.3 Future OAuth Integration
|
||||
|
||||
- Support for enterprise SSO (Single Sign-On)
|
||||
- Integration with identity providers (Azure AD, Okta, Keycloak)
|
||||
- Backward compatibility with local authentication during migration
|
||||
|
||||
### 3.3 API Design Principles
|
||||
|
||||
- RESTful resource-based endpoints (e.g., `/api/applications`, `/api/deployments`)
|
||||
- Consistent HTTP verb usage (GET, POST, PUT, DELETE, PATCH)
|
||||
- Pagination for list endpoints
|
||||
- Filtering and sorting capabilities
|
||||
- HATEOAS support for discoverability (optional)
|
||||
- Versioned API (e.g., `/api/v1/...`)
|
||||
|
||||
### 3.4 Data Persistence Strategy
|
||||
|
||||
- **Entity Mapping**: JPA entities with Hibernate annotations
|
||||
- **Relationship Management**: Appropriate use of @OneToMany, @ManyToOne, @ManyToMany
|
||||
- **Cascade Operations**: Carefully configured cascade types to maintain referential integrity
|
||||
- **Lazy/Eager Loading**: Optimized fetch strategies to prevent N+1 queries
|
||||
- **Auditing**: Automatic timestamp management using `@CreatedDate` and `@LastModifiedDate`
|
||||
|
||||
## 4. Functional Requirements
|
||||
|
||||
### 4.1 Business Unit Management
|
||||
|
||||
**Description**: Organizations are structured around business units that own and manage applications.
|
||||
|
||||
**Requirements**:
|
||||
|
||||
- Each business unit must have a unique name
|
||||
- Business units must maintain a list of associated contacts with specific roles (Director, Program Manager, etc.)
|
||||
- Support for hierarchical contact management with role-based assignments
|
||||
|
||||
**Data Model**:
|
||||
|
||||
- Business Unit entity with name and metadata
|
||||
- Many-to-many relationship with Contact entities
|
||||
- Role specification for each business unit contact
|
||||
|
||||
**API Endpoints**:
|
||||
|
||||
- `GET /api/business-units` - List all business units
|
||||
- `GET /api/business-units/{id}` - Get business unit details
|
||||
- `POST /api/business-units` - Create new business unit
|
||||
- `PUT /api/business-units/{id}` - Update business unit
|
||||
- `DELETE /api/business-units/{id}` - Delete business unit
|
||||
- `GET /api/business-units/{id}/contacts` - Get contacts for business unit
|
||||
|
||||
### 4.2 Application Management
|
||||
|
||||
**Description**: Applications are the core entities tracked within the system, representing software systems deployed across various environments.
|
||||
|
||||
**Requirements**:
|
||||
|
||||
#### 4.2.1 Application Lifecycle Status
|
||||
|
||||
Applications must track their current status through the following states:
|
||||
|
||||
- **IDEA**: Initial concept phase, not yet in development
|
||||
- **IN_DEVELOPMENT**: Active development in progress
|
||||
- **IN_SERVICE**: Deployed and operational in production
|
||||
- **MAINTENANCE**: Undergoing maintenance or limited support
|
||||
- **DECOMMISSIONED**: Retired and no longer in use
|
||||
|
||||
Status transitions should be tracked with timestamps for audit purposes.
|
||||
|
||||
#### 4.2.2 Multi-Environment Deployment
|
||||
|
||||
- Applications must support deployment across multiple environments
|
||||
- Each deployment must be linked to a specific version of the application
|
||||
- Complete deployment history must be maintained with timestamps
|
||||
- Deployment tracking must record who deployed and when
|
||||
|
||||
#### 4.2.3 Stakeholder Management
|
||||
|
||||
- Applications must maintain a list of contacts
|
||||
- Each contact must be associated with a specific role (Product Owner, Functional Authority, Developer, Maintainer, etc.)
|
||||
- Support for multiple stakeholders per role
|
||||
- Contact information must include name, email, and phone number
|
||||
|
||||
#### 4.2.4 Service Level Agreements
|
||||
|
||||
- Each application must be associated with an SLA definition
|
||||
- SLA compliance must be trackable
|
||||
|
||||
#### 4.2.5 Technical Documentation
|
||||
|
||||
- Applications must support multiple technical documentation references
|
||||
- Each documentation entry must include:
|
||||
- Title
|
||||
- URL reference
|
||||
- Creation and update timestamps
|
||||
|
||||
#### 4.2.6 Lifecycle Management
|
||||
|
||||
- End-of-life date tracking
|
||||
- End-of-support date tracking
|
||||
- Version-specific lifecycle information
|
||||
|
||||
#### 4.2.7 External Dependencies
|
||||
|
||||
- Applications must be able to reference multiple external dependencies
|
||||
- Dependencies can be of various types (detailed in section 4.4)
|
||||
|
||||
**Data Model**:
|
||||
|
||||
- Application entity with status tracking (enum: IDEA, IN_DEVELOPMENT, IN_SERVICE, MAINTENANCE, DECOMMISSIONED)
|
||||
- Relationship to Business Unit (many-to-one)
|
||||
- Relationship to SLA (optional, one-to-one)
|
||||
- Relationship to Versions (one-to-many)
|
||||
- Relationship to Contacts (many-to-many)
|
||||
- Relationship to Technical Documentation (one-to-many)
|
||||
- Relationship to External Dependencies (one-to-many)
|
||||
|
||||
**API Endpoints**:
|
||||
|
||||
- `GET /api/applications` - List applications (with filtering by status, business unit)
|
||||
- `GET /api/applications/{id}` - Get application details
|
||||
- `POST /api/applications` - Create new application
|
||||
- `PUT /api/applications/{id}` - Update application
|
||||
- `PATCH /api/applications/{id}/status` - Update application status
|
||||
- `DELETE /api/applications/{id}` - Delete application
|
||||
- `GET /api/applications/{id}/versions` - Get versions for application
|
||||
- `GET /api/applications/{id}/deployments` - Get deployment history
|
||||
- `GET /api/applications/{id}/contacts` - Get stakeholders
|
||||
- `GET /api/applications/{id}/dependencies` - Get external dependencies
|
||||
|
||||
### 4.3 Version Management
|
||||
|
||||
**Description**: Each application release is tracked as a distinct version with specific attributes.
|
||||
|
||||
**Requirements**:
|
||||
|
||||
- Every deployed application must be linked to a specific version
|
||||
- Version tracking must include:
|
||||
- **Version Identifier**: Semantic version or custom identifier (e.g., "1.2.3", "2024.Q1")
|
||||
- **External Reference**: Link to source control, ticketing system, or release notes
|
||||
- **Release Date**: When the version was officially released
|
||||
- **End-of-Life Date**: When support for this version ends
|
||||
- **Creation Timestamp**: When the version record was created
|
||||
|
||||
**Data Model**:
|
||||
|
||||
- Version entity linked to Application (many-to-one)
|
||||
- Unique identifier and version metadata
|
||||
- Lifecycle dates specific to the version
|
||||
- Constraint: Version identifier must be unique within an application
|
||||
|
||||
**API Endpoints**:
|
||||
|
||||
- `GET /api/applications/{appId}/versions` - List versions for an application
|
||||
- `GET /api/versions/{id}` - Get version details
|
||||
- `POST /api/applications/{appId}/versions` - Create new version
|
||||
- `PUT /api/versions/{id}` - Update version
|
||||
- `DELETE /api/versions/{id}` - Delete version
|
||||
|
||||
### 4.4 External Dependencies Management
|
||||
|
||||
**Description**: Applications often rely on external data sources and services. These dependencies must be documented and tracked.
|
||||
|
||||
**Requirements**:
|
||||
|
||||
#### 4.4.1 Dependency Types
|
||||
|
||||
External dependencies can be classified into the following types:
|
||||
|
||||
- **WEB_SERVICE**: REST APIs, SOAP services, microservices
|
||||
- **DATABASE**: External database connections
|
||||
- **CERTIFICATE**: SSL/TLS certificates, authentication certificates
|
||||
- **NETWORK_FLOW**: Network connections, firewall rules, VPN tunnels
|
||||
|
||||
#### 4.4.2 Dependency Documentation
|
||||
|
||||
Each external dependency must include:
|
||||
|
||||
- Name and type classification
|
||||
- Descriptive documentation (free text)
|
||||
- Technical documentation specific to the dependency
|
||||
- Creation and update timestamps
|
||||
|
||||
#### 4.4.3 Data Usage Agreements
|
||||
|
||||
- External dependencies must be linkable to one or more Data Usage Agreements
|
||||
- This enables tracking of data governance and compliance requirements
|
||||
|
||||
**Data Model**:
|
||||
|
||||
- External Dependency entity with type enumeration
|
||||
- Relationship to Application (many-to-one)
|
||||
- Relationship to Data Usage Agreements (many-to-many)
|
||||
|
||||
**API Endpoints**:
|
||||
|
||||
- `GET /api/applications/{appId}/dependencies` - List dependencies for application
|
||||
- `GET /api/dependencies/{id}` - Get dependency details
|
||||
- `POST /api/applications/{appId}/dependencies` - Create new dependency
|
||||
- `PUT /api/dependencies/{id}` - Update dependency
|
||||
- `DELETE /api/dependencies/{id}` - Delete dependency
|
||||
- `GET /api/dependencies/{id}/agreements` - Get data usage agreements for dependency
|
||||
|
||||
### 4.5 Data Usage Agreements
|
||||
|
||||
**Description**: Data Usage Agreements formalize the authorization to use external data sources and must be tracked for compliance purposes.
|
||||
|
||||
**Requirements**: Each Data Usage Agreement must contain:
|
||||
|
||||
- **Data Nature**: Description of the type of data covered by the agreement
|
||||
- **Documentation Link**: Reference to the legal or formal agreement document
|
||||
- **Validity Start Date**: When the agreement becomes effective
|
||||
- **Validity End Date**: When the agreement expires (optional for indefinite agreements)
|
||||
- **Creation Timestamp**: When the agreement record was created
|
||||
|
||||
**Data Model**:
|
||||
|
||||
- Data Usage Agreement entity with validity period
|
||||
- Many-to-many relationship with External Dependencies
|
||||
|
||||
**API Endpoints**:
|
||||
|
||||
- `GET /api/data-usage-agreements` - List all agreements (with expiration filtering)
|
||||
- `GET /api/data-usage-agreements/{id}` - Get agreement details
|
||||
- `POST /api/data-usage-agreements` - Create new agreement
|
||||
- `PUT /api/data-usage-agreements/{id}` - Update agreement
|
||||
- `DELETE /api/data-usage-agreements/{id}` - Delete agreement
|
||||
|
||||
### 4.6 Environment Management
|
||||
|
||||
**Description**: Environments represent distinct deployment targets where applications can be installed. Unlike traditional fixed environment types, LDPv2 treats environments as flexible entities that can be created and configured as needed.
|
||||
|
||||
**Requirements**:
|
||||
|
||||
#### 4.6.1 Environment as First-Class Entity
|
||||
|
||||
Each environment is a distinct entity with its own attributes and lifecycle. This allows for:
|
||||
|
||||
- Multiple production environments (e.g., PROD-EU, PROD-US, PROD-ASIA)
|
||||
- Team-specific development environments (e.g., DEV-TeamAlpha, DEV-TeamBeta)
|
||||
- Customer-specific environments
|
||||
- Temporary or experimental environments
|
||||
|
||||
#### 4.6.2 Environment Attributes
|
||||
|
||||
Each environment must be tracked with the following attributes:
|
||||
|
||||
- **Name**: Unique identifier for the environment (e.g., "PROD-EU", "INT-QA", "DEV-Mobile")
|
||||
- **Description**: Optional free-text description of the environment's purpose
|
||||
- **Production Flag**: Boolean indicator to identify production environments
|
||||
- **Criticality Level**: Numeric rating (e.g., 1-5) to prioritize monitoring, incident response, and deployment approvals
|
||||
- Level 5: Critical production environments
|
||||
- Level 4: Important pre-production environments
|
||||
- Level 3: Integration and testing environments
|
||||
- Level 2: Development environments
|
||||
- Level 1: Experimental or temporary environments
|
||||
- **Timestamps**: Creation and update tracking for audit purposes
|
||||
|
||||
#### 4.6.3 Environment Flexibility
|
||||
|
||||
- Environments can be created, updated, and deactivated as needed
|
||||
- No hard-coded list of environments in the application code
|
||||
- Support for environment-specific security roles and permissions
|
||||
- Environments can be organized or tagged for better management (future enhancement)
|
||||
|
||||
#### 4.6.4 Environment-Based Access Control
|
||||
|
||||
- Users can have different permissions per environment
|
||||
- Critical environments (high criticality level or production flag) may require additional approval workflows
|
||||
- Deployment permissions should be configurable per environment
|
||||
|
||||
**Data Model**:
|
||||
|
||||
- Environment entity with flexible attributes
|
||||
- No enumeration constraints on environment names
|
||||
- Referenced by Deployment entity for tracking application versions
|
||||
- Potential for environment grouping or categorization (future)
|
||||
|
||||
**API Endpoints**:
|
||||
|
||||
- `GET /api/environments` - List all environments (with filtering by production flag, criticality)
|
||||
- `GET /api/environments/{id}` - Get environment details
|
||||
- `POST /api/environments` - Create new environment
|
||||
- `PUT /api/environments/{id}` - Update environment
|
||||
- `DELETE /api/environments/{id}` - Deactivate/delete environment
|
||||
- `GET /api/environments/{id}/deployments` - Get all deployments in this environment
|
||||
|
||||
**Security Considerations**:
|
||||
|
||||
- Creating or modifying production environments should require elevated privileges
|
||||
- Environment deletion should be soft delete to preserve deployment history
|
||||
- Audit logging for all environment changes
|
||||
|
||||
### 4.7 Deployment Tracking
|
||||
|
||||
**Description**: Deployments represent the installation of a specific application version to a specific environment.
|
||||
|
||||
**Requirements**:
|
||||
|
||||
#### 4.7.1 Deployment Definition
|
||||
|
||||
A deployment is uniquely defined by the combination of:
|
||||
|
||||
- Application (which application)
|
||||
- Version (which release)
|
||||
- Environment (where it's deployed)
|
||||
|
||||
#### 4.7.2 Deployment History
|
||||
|
||||
- Complete deployment history must be maintained (immutable records)
|
||||
- Each deployment record must include:
|
||||
- Deployment timestamp
|
||||
- User or system that performed the deployment
|
||||
- Optional notes or comments
|
||||
- Creation timestamp for audit purposes
|
||||
|
||||
#### 4.7.3 Current State Tracking
|
||||
|
||||
- The system must be able to identify the currently active version in each environment
|
||||
- This is determined by the most recent deployment for a given application-environment combination
|
||||
- A dedicated API endpoint should provide current deployment state
|
||||
|
||||
**Data Model**:
|
||||
|
||||
- Deployment entity with foreign keys to Application, Version, and Environment
|
||||
- Timestamp-based ordering for historical tracking
|
||||
- Business logic to determine "current" deployment (most recent by deployment date)
|
||||
|
||||
**API Endpoints**:
|
||||
|
||||
- `GET /api/deployments` - List all deployments (with filtering)
|
||||
- `GET /api/deployments/{id}` - Get deployment details
|
||||
- `POST /api/deployments` - Record new deployment
|
||||
- `GET /api/applications/{appId}/deployments/current` - Get current deployments per environment
|
||||
- `GET /api/environments/{envId}/deployments/current` - Get all current deployments in environment
|
||||
- `GET /api/deployments/history?applicationId={appId}&environmentId={envId}` - Deployment history for app in env
|
||||
|
||||
**Business Rules**:
|
||||
|
||||
- Deployments are immutable once created (no updates, only new deployments)
|
||||
- Deployment dates cannot be in the future
|
||||
- Version must belong to the specified application
|
||||
|
||||
### 4.8 Contact and Stakeholder Management
|
||||
|
||||
**Description**: Contacts represent roles and responsibilities associated with applications, business units, and SLAs.
|
||||
|
||||
**Requirements**:
|
||||
|
||||
#### 4.8.1 Contact Roles
|
||||
|
||||
The system must support various contact roles including but not limited to:
|
||||
|
||||
- Product Owner
|
||||
- Functional Authority
|
||||
- Developer
|
||||
- Maintainer
|
||||
- Technical Lead
|
||||
- Business Analyst
|
||||
- Director
|
||||
- Program Manager
|
||||
|
||||
Roles should be configurable and extensible.
|
||||
|
||||
#### 4.8.2 Contact Structure
|
||||
|
||||
A contact represents a functional role that can be associated with:
|
||||
|
||||
- One or more named individuals (persons)
|
||||
- Multiple applications
|
||||
- Business units
|
||||
- SLAs
|
||||
|
||||
#### 4.8.3 Person Information
|
||||
|
||||
Each person assigned to a contact must have:
|
||||
|
||||
- First name and last name
|
||||
- Email address (required, unique)
|
||||
- Phone number (optional)
|
||||
- Primary contact designation (one person per contact should be marked as primary)
|
||||
|
||||
#### 4.8.4 Contact Relationships
|
||||
|
||||
Contacts must be linkable to:
|
||||
|
||||
- Applications (with application-specific roles)
|
||||
- Business Units (with organizational roles)
|
||||
- SLAs (as responsible parties for service delivery)
|
||||
|
||||
**Data Model**:
|
||||
|
||||
- ContactRole entity defining available roles
|
||||
- Contact entity representing the functional position
|
||||
- Person entity with individual contact details
|
||||
- Junction tables for Contact-Person, Application-Contact, BusinessUnit-Contact, and SLA-Contact relationships
|
||||
|
||||
**API Endpoints**:
|
||||
|
||||
- `GET /api/contact-roles` - List available contact roles
|
||||
- `GET /api/contacts` - List all contacts
|
||||
- `GET /api/contacts/{id}` - Get contact details with persons
|
||||
- `POST /api/contacts` - Create new contact
|
||||
- `PUT /api/contacts/{id}` - Update contact
|
||||
- `DELETE /api/contacts/{id}` - Delete contact
|
||||
- `GET /api/persons` - List all persons
|
||||
- `GET /api/persons/{id}` - Get person details
|
||||
- `POST /api/persons` - Create new person
|
||||
- `PUT /api/persons/{id}` - Update person
|
||||
|
||||
### 4.9 Service Level Agreement (SLA) Management
|
||||
|
||||
**Description**: SLAs define the expected service levels, maintenance windows, and responsibilities for applications.
|
||||
|
||||
**Requirements**:
|
||||
|
||||
#### 4.9.1 Core SLA Metrics
|
||||
|
||||
Each SLA must define:
|
||||
|
||||
- **Availability Percentage**: Expected uptime (e.g., 99.9%)
|
||||
- **Minimum Average Response Time**: Expected response time in seconds
|
||||
- **Reaction Time**: Time to respond to incidents (as text description)
|
||||
|
||||
#### 4.9.2 Maintenance Windows
|
||||
|
||||
- SLAs must support multiple maintenance windows
|
||||
- Each maintenance window must specify:
|
||||
- Day of the week (MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY)
|
||||
- Start time (HH:MM format)
|
||||
- End time (HH:MM format)
|
||||
- Multiple maintenance windows can be defined for the same SLA
|
||||
|
||||
#### 4.9.3 Critical Periods
|
||||
|
||||
- SLAs must track critical periods when higher service levels are required
|
||||
- Each critical period must include:
|
||||
- Start datetime
|
||||
- End datetime
|
||||
- Duration in minutes
|
||||
- Optional description
|
||||
|
||||
#### 4.9.4 SLA Documentation
|
||||
|
||||
- **Diagram**: Support for storing draw.io diagrams in JSON format showing system architecture and dependencies
|
||||
- **Dependencies Description**: Free-text description of system dependencies
|
||||
- **Responsibility Scope**: Clear definition of what is and isn't covered by the SLA
|
||||
|
||||
#### 4.9.5 SLA Contacts
|
||||
|
||||
- Multiple contacts must be assignable to each SLA
|
||||
- These represent the responsible parties for maintaining service levels
|
||||
|
||||
**Data Model**:
|
||||
|
||||
- SLA entity with metrics and documentation
|
||||
- MaintenanceWindow entity (one-to-many from SLA)
|
||||
- CriticalPeriod entity (one-to-many from SLA)
|
||||
- SLA-Contact junction table (many-to-many)
|
||||
|
||||
**API Endpoints**:
|
||||
|
||||
- `GET /api/slas` - List all SLAs
|
||||
- `GET /api/slas/{id}` - Get SLA details
|
||||
- `POST /api/slas` - Create new SLA
|
||||
- `PUT /api/slas/{id}` - Update SLA
|
||||
- `DELETE /api/slas/{id}` - Delete SLA
|
||||
- `GET /api/slas/{id}/maintenance-windows` - Get maintenance windows
|
||||
- `POST /api/slas/{id}/maintenance-windows` - Add maintenance window
|
||||
- `GET /api/slas/{id}/critical-periods` - Get critical periods
|
||||
- `POST /api/slas/{id}/critical-periods` - Add critical period
|
||||
|
||||
## 5. Data Model Summary
|
||||
|
||||
### 5.1 Core Entities
|
||||
|
||||
1. **BusinessUnit**: Organizational container for applications
|
||||
2. **Application**: Central entity representing software systems
|
||||
3. **Version**: Releases of applications
|
||||
4. **Environment**: Flexible deployment targets with custom names and attributes
|
||||
5. **Deployment**: Records of version deployments to environments
|
||||
6. **Person**: Individual stakeholders
|
||||
7. **ContactRole**: Predefined roles for stakeholders
|
||||
8. **Contact**: Functional positions held by persons
|
||||
9. **TechnicalDocumentation**: Links to technical resources
|
||||
10. **ExternalDependency**: External services and data sources
|
||||
11. **DataUsageAgreement**: Legal agreements for data usage
|
||||
12. **SLA**: Service level agreement definitions
|
||||
13. **MaintenanceWindow**: Scheduled maintenance periods
|
||||
14. **CriticalPeriod**: High-priority time windows
|
||||
|
||||
### 5.2 Relationship Summary
|
||||
|
||||
- BusinessUnit → Application (1:N)
|
||||
- Application → Version (1:N)
|
||||
- Application + Version + Environment → Deployment (unique combination)
|
||||
- Application ↔ Contact (N:N)
|
||||
- Application → ExternalDependency (1:N)
|
||||
- Application → TechnicalDocumentation (1:N)
|
||||
- Application → SLA (1:1, optional)
|
||||
- ExternalDependency ↔ DataUsageAgreement (N:N)
|
||||
- Contact ↔ Person (N:N)
|
||||
- SLA → MaintenanceWindow (1:N)
|
||||
- SLA → CriticalPeriod (1:N)
|
||||
- SLA ↔ Contact (N:N)
|
||||
|
||||
### 5.3 Database Schema Considerations
|
||||
|
||||
- All primary keys: UUID type
|
||||
- Foreign keys with appropriate CASCADE/RESTRICT rules
|
||||
- Indexes on frequently queried fields (application status, environment production flag, deployment dates)
|
||||
- Unique constraints where applicable (email in Person, environment name)
|
||||
- Audit columns (createdAt, updatedAt) on all entities using JPA auditing
|
||||
|
||||
## 6. Non-Functional Requirements
|
||||
|
||||
### 6.1 Performance
|
||||
|
||||
- API response time < 500ms for 95% of requests
|
||||
- Support for pagination on all list endpoints (default page size: 20)
|
||||
- Efficient query optimization to prevent N+1 problems
|
||||
- Database connection pooling (HikariCP)
|
||||
- Caching strategy for reference data (contact roles, environments)
|
||||
|
||||
### 6.2 Security
|
||||
|
||||
- JWT token expiration: 1 hour (configurable)
|
||||
- Refresh token mechanism for session extension
|
||||
- Password hashing: BCrypt with appropriate work factor
|
||||
- HTTPS only in production
|
||||
- CORS configuration for frontend origin
|
||||
- SQL injection prevention via parameterized queries (JPA)
|
||||
- XSS protection via Angular sanitization
|
||||
- CSRF protection via Spring Security
|
||||
|
||||
### 6.3 Audit and Compliance
|
||||
|
||||
- All entities must track creation and update timestamps
|
||||
- Deployment history must be immutable for audit purposes
|
||||
- Data Usage Agreement expiration must be trackable
|
||||
- User actions should be logged (who did what, when)
|
||||
- Database audit trail for sensitive operations
|
||||
|
||||
### 6.4 Data Integrity
|
||||
|
||||
- Foreign key constraints enforced at database level
|
||||
- Validation annotations on JPA entities (@NotNull, @Size, @Email, etc.)
|
||||
- Business rule validation in service layer
|
||||
- Transaction management for complex operations
|
||||
- Soft delete for critical entities to preserve referential integrity
|
||||
|
||||
### 6.5 Scalability
|
||||
|
||||
- The system must support hundreds of applications
|
||||
- Deployment history may grow to thousands of records per application
|
||||
- Efficient querying of current deployment states is critical
|
||||
- Database indexing strategy for performance
|
||||
- Potential for read replicas if query load increases
|
||||
|
||||
### 6.6 Maintainability
|
||||
|
||||
- Clean separation of concerns (Controller → Service → Repository)
|
||||
- DTOs for API layer to decouple from entity model
|
||||
- MapStruct or ModelMapper for DTO conversion
|
||||
- Comprehensive API documentation (Swagger/OpenAPI)
|
||||
- Unit tests (JUnit 5, Mockito) with >80% code coverage
|
||||
- Integration tests for critical workflows
|
||||
- Docker containerization for consistent deployments
|
||||
|
||||
### 6.7 Usability
|
||||
|
||||
- Intuitive Angular UI with responsive design
|
||||
- Clear error messages and validation feedback
|
||||
- Loading indicators for async operations
|
||||
- Confirmation dialogs for destructive actions
|
||||
- Keyboard navigation support
|
||||
- Accessibility compliance (WCAG 2.1 Level AA)
|
||||
|
||||
## 7. Implementation Phases
|
||||
|
||||
### 7.1 Phase 1: Core Foundation (MVP)
|
||||
|
||||
- Database schema creation with Liquibase/Flyway
|
||||
- JPA entity model implementation
|
||||
- Spring Security with local authentication
|
||||
- JWT token generation and validation
|
||||
- Basic CRUD APIs for:
|
||||
- BusinessUnit
|
||||
- Application (with status tracking)
|
||||
- Environment
|
||||
- Contact and Person
|
||||
- Angular authentication module
|
||||
- Basic application listing and detail views
|
||||
|
||||
### 7.2 Phase 2: Deployment Tracking
|
||||
|
||||
- Version entity and APIs
|
||||
- Deployment entity and APIs
|
||||
- Deployment history tracking
|
||||
- Current deployment state queries
|
||||
- Angular deployment management interface
|
||||
- Deployment timeline visualization
|
||||
|
||||
### 7.3 Phase 3: Dependencies and Compliance
|
||||
|
||||
- External Dependency entity and APIs
|
||||
- Data Usage Agreement entity and APIs
|
||||
- Dependency-Agreement linkage
|
||||
- Technical Documentation management
|
||||
- Angular forms for dependency tracking
|
||||
- Expiration alerts for agreements
|
||||
|
||||
### 7.4 Phase 4: SLA Management
|
||||
|
||||
- SLA entity and APIs
|
||||
- Maintenance Window management
|
||||
- Critical Period tracking
|
||||
- SLA-Contact relationships
|
||||
- Draw.io diagram storage and display
|
||||
- Angular SLA management interface
|
||||
|
||||
### 7.5 Phase 5: Advanced Features
|
||||
|
||||
- Environment-based role permissions
|
||||
- OAuth 2.0 integration
|
||||
- Advanced search and filtering
|
||||
- Dashboard and analytics
|
||||
- Reporting capabilities
|
||||
- Notification system
|
||||
- API rate limiting
|
||||
|
||||
## 8. Testing Strategy
|
||||
|
||||
### 8.1 Backend Testing
|
||||
|
||||
- **Unit Tests**: Service layer business logic (JUnit 5, Mockito)
|
||||
- **Integration Tests**: Repository layer with test database (Testcontainers)
|
||||
- **API Tests**: Controller endpoints (MockMvc, REST Assured)
|
||||
- **Security Tests**: Authentication and authorization flows
|
||||
- **Performance Tests**: Load testing for critical endpoints (JMeter, Gatling)
|
||||
|
||||
### 8.2 Frontend Testing
|
||||
|
||||
- **Unit Tests**: Angular components and services (Jasmine, Karma)
|
||||
- **Integration Tests**: Component interaction and routing
|
||||
- **E2E Tests**: Critical user workflows (Cypress, Playwright)
|
||||
- **Accessibility Tests**: WCAG compliance checking
|
||||
|
||||
### 8.3 Test Coverage Goals
|
||||
|
||||
- Backend code coverage: >80%
|
||||
- Frontend code coverage: >70%
|
||||
- Critical path E2E coverage: 100%
|
||||
|
||||
## 9. Deployment Architecture
|
||||
|
||||
### 9.1 Development Environment
|
||||
|
||||
- Local PostgreSQL instance via Docker
|
||||
- Spring Boot running on port 8080
|
||||
- Angular dev server on port 4200
|
||||
- Hot reload enabled for both frontend and backend
|
||||
|
||||
### 9.2 Production Environment
|
||||
|
||||
- Containerized deployment (Docker/Kubernetes)
|
||||
- PostgreSQL cluster with replication
|
||||
- Load balancer for backend instances
|
||||
- CDN for frontend static assets
|
||||
- Separate database for each environment (dev, test, prod)
|
||||
- Automated backup strategy
|
||||
|
||||
### 9.3 CI/CD Pipeline
|
||||
|
||||
- Source control: Git (GitHub, GitLab, or Bitbucket)
|
||||
- Build automation: Maven for backend, npm for frontend
|
||||
- Continuous Integration: Jenkins, GitLab CI, or GitHub Actions
|
||||
- Automated testing in pipeline
|
||||
- Docker image building and publishing
|
||||
- Automated deployment to test environments
|
||||
- Manual approval for production deployment
|
||||
|
||||
## 10. Documentation Requirements
|
||||
|
||||
### 10.1 Technical Documentation
|
||||
|
||||
- API documentation (Swagger/OpenAPI specification)
|
||||
- Database schema documentation (ER diagrams)
|
||||
- Architecture decision records (ADRs)
|
||||
- Deployment and configuration guides
|
||||
- Security best practices guide
|
||||
|
||||
### 10.2 User Documentation
|
||||
|
||||
- User manual for each user role
|
||||
- Quick start guide
|
||||
- Video tutorials for common workflows
|
||||
- FAQ section
|
||||
- Troubleshooting guide
|
||||
|
||||
## 11. Future Considerations
|
||||
|
||||
### 11.1 Potential Enhancements
|
||||
|
||||
- Integration with CI/CD pipelines for automatic deployment recording
|
||||
- Automated SLA compliance monitoring and alerting
|
||||
- Dashboard views for application portfolio management
|
||||
- Notification system for expiring Data Usage Agreements
|
||||
- Advanced reporting and analytics
|
||||
- Mobile application for on-the-go access
|
||||
- Webhook support for external integrations
|
||||
- GraphQL API as alternative to REST
|
||||
- Elasticsearch integration for advanced search
|
||||
- Audit log viewer with filtering
|
||||
|
||||
### 11.2 Reporting Requirements
|
||||
|
||||
- Application inventory reports by status
|
||||
- Deployment frequency analytics
|
||||
- Environment utilization reports
|
||||
- SLA compliance reporting
|
||||
- Dependency mapping and impact analysis
|
||||
- End-of-life planning reports
|
||||
- Data usage agreement expiration forecasts
|
||||
- Stakeholder contact directory
|
||||
|
||||
## 12. Success Criteria
|
||||
|
||||
The LDPv2 system will be considered successful when:
|
||||
|
||||
1. All applications within the business unit are accurately documented
|
||||
2. Deployment history is complete and traceable across all environments
|
||||
3. Stakeholders can easily identify current application states and ownership
|
||||
4. Compliance officers can track data usage agreements effectively
|
||||
5. SLA definitions are clearly documented and accessible
|
||||
6. The system serves as the single source of truth for application lifecycle data
|
||||
7. Users can perform all core functions without training (intuitive UI)
|
||||
8. System uptime > 99.5%
|
||||
9. User satisfaction score > 4.0/5.0
|
||||
|
||||
----------
|
||||
|
||||
**Document Version**: 2.0
|
||||
**Last Updated**: February 2026
|
||||
**Status**: Technical Specification - Ready for Development
|
||||
**Prepared By**: Laurent
|
||||
**Review Date**: To be scheduled
|
||||
+335
@@ -0,0 +1,335 @@
|
||||
# LDPv2 MVP - Development Package
|
||||
|
||||
Welcome to the LDPv2 (Lifecycle Data Platform v2) MVP development package!
|
||||
|
||||
This package contains complete documentation and specifications for building the LDPv2 application using an iterative, story-based approach.
|
||||
|
||||
---
|
||||
|
||||
## 📦 Package Contents
|
||||
|
||||
```
|
||||
ldpv2-mvp/
|
||||
├── README.md (this file)
|
||||
├── 00-MVP-OVERVIEW.md
|
||||
├── 01-TECHNICAL-SETUP.md
|
||||
├── stories/
|
||||
│ ├── STORY-0-Foundation.md
|
||||
│ ├── STORY-1-Business-Units.md
|
||||
│ ├── STORY-2-Applications.md
|
||||
│ ├── STORY-3-Contacts.md
|
||||
│ ├── STORY-4-Environments.md
|
||||
│ ├── STORY-5-Versions.md
|
||||
│ ├── STORY-6-Deployments.md
|
||||
│ └── STORY-7-Current-State-History.md
|
||||
├── data-model/
|
||||
│ └── complete-data-model.ts
|
||||
└── api-specs/
|
||||
└── endpoint-summary.md
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Quick Start
|
||||
|
||||
### Step 1: Read the Overview
|
||||
Start with **00-MVP-OVERVIEW.md** to understand:
|
||||
- MVP scope and objectives
|
||||
- Development approach (Walking Skeleton + Vertical Slices)
|
||||
- Story dependencies
|
||||
- Timeline estimates
|
||||
|
||||
### Step 2: Setup Your Environment
|
||||
Follow **01-TECHNICAL-SETUP.md** to:
|
||||
- Install prerequisites (Java 17+, Node.js 18+, PostgreSQL 16, Docker)
|
||||
- Setup Spring Boot backend project
|
||||
- Setup Angular 18 frontend project
|
||||
- Configure Docker Compose for local development
|
||||
- Understand project structure and conventions
|
||||
|
||||
### Step 3: Start Development
|
||||
Begin with **Story 0** (Foundation) and follow the story sequence:
|
||||
|
||||
```
|
||||
Story 0: Foundation (Walking Skeleton)
|
||||
↓
|
||||
Story 1: Business Units
|
||||
↓
|
||||
Story 2: Applications
|
||||
↓
|
||||
Story 3: Contacts (can be parallel with Story 4)
|
||||
↓
|
||||
Story 4: Environments (enhancement)
|
||||
↓
|
||||
Story 5: Versions
|
||||
↓
|
||||
Story 6: Deployments
|
||||
↓
|
||||
Story 7: Current State & History
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📋 Story Structure
|
||||
|
||||
Each story follows a consistent structure:
|
||||
|
||||
- **Story Overview**: Business value and objectives
|
||||
- **Scope**: What's in and out of scope
|
||||
- **Technical Implementation**: Detailed backend and frontend tasks
|
||||
- **Acceptance Criteria**: Testable requirements
|
||||
- **Testing Scenarios**: Step-by-step test cases
|
||||
- **Definition of Done**: Checklist before considering story complete
|
||||
|
||||
---
|
||||
|
||||
## 🎯 MVP Scope Summary
|
||||
|
||||
### What's Included in MVP
|
||||
|
||||
✅ **Core Domain**
|
||||
- Application management with lifecycle tracking
|
||||
- Business unit organization
|
||||
- Environment management (flexible, production-ready)
|
||||
- Version tracking
|
||||
- Deployment recording and history
|
||||
- Current deployment state queries
|
||||
|
||||
✅ **User Management**
|
||||
- Local authentication (JWT-based)
|
||||
- Basic role-based access control (ADMIN, USER)
|
||||
- User registration and login
|
||||
|
||||
✅ **Contact Management**
|
||||
- Contact roles (Product Owner, Developer, etc.)
|
||||
- Person management
|
||||
- Contact-Person associations
|
||||
|
||||
✅ **Reporting & Analytics**
|
||||
- Deployment dashboard
|
||||
- Deployment history and timeline
|
||||
- Statistics and charts
|
||||
- Export to CSV/Excel
|
||||
|
||||
### What's NOT in MVP (Phase 2)
|
||||
|
||||
❌ External dependencies tracking
|
||||
❌ Data usage agreements
|
||||
❌ SLA management
|
||||
❌ Technical documentation links
|
||||
❌ OAuth integration
|
||||
❌ Advanced notifications
|
||||
❌ Deployment approval workflows
|
||||
❌ CI/CD integration
|
||||
|
||||
---
|
||||
|
||||
## 🏗️ Technology Stack
|
||||
|
||||
### Backend
|
||||
- **Framework**: Spring Boot 3.2.x
|
||||
- **Language**: Java 17/21
|
||||
- **Security**: Spring Security + JWT
|
||||
- **Database**: PostgreSQL 16
|
||||
- **ORM**: Hibernate (JPA)
|
||||
- **Migrations**: Liquibase
|
||||
- **Testing**: JUnit 5, Mockito, Testcontainers
|
||||
|
||||
### Frontend
|
||||
- **Framework**: Angular 18
|
||||
- **Language**: TypeScript 5.x
|
||||
- **Auth**: JWT interceptors
|
||||
- **UI Library**: Angular Material or PrimeNG
|
||||
- **Testing**: Jasmine/Karma, Cypress
|
||||
|
||||
### DevOps
|
||||
- **Containerization**: Docker
|
||||
- **Orchestration**: Docker Compose
|
||||
- **CI/CD**: Jenkins/GitLab CI/GitHub Actions
|
||||
|
||||
---
|
||||
|
||||
## ⏱️ Timeline Estimate
|
||||
|
||||
| Phase | Duration | Stories |
|
||||
|-------|----------|---------|
|
||||
| **Phase 0: Foundation** | 2-3 weeks | Story 0 |
|
||||
| **Phase 1: Core (Batch 1)** | 3-4 weeks | Stories 1-4 |
|
||||
| **Phase 1: Core (Batch 2)** | 3-4 weeks | Stories 5-7 |
|
||||
| **Total MVP** | **8-11 weeks** | **8 stories** |
|
||||
|
||||
*Based on 1 full-time developer or 2 part-time developers*
|
||||
|
||||
---
|
||||
|
||||
## 📊 Story Dependencies Graph
|
||||
|
||||
```
|
||||
Story 0 (Foundation)
|
||||
├── Story 1 (Business Units) ────────┐
|
||||
│ └── Story 2 (Applications) ──────┤
|
||||
├── Story 3 (Contacts) ──────────────┤── Can be developed in parallel
|
||||
├── Story 4 (Environments) ──────────┘
|
||||
└── Story 5 (Versions)
|
||||
└── Story 6 (Deployments)
|
||||
└── Story 7 (Current State & History)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ✅ Success Criteria
|
||||
|
||||
The MVP will be considered successful when:
|
||||
|
||||
1. **Functional Completeness**
|
||||
- All 8 stories delivered and accepted
|
||||
- All acceptance criteria met
|
||||
- Zero critical bugs
|
||||
|
||||
2. **Technical Quality**
|
||||
- Backend test coverage > 80%
|
||||
- Frontend test coverage > 70%
|
||||
- All APIs documented in Swagger
|
||||
- Code passes security review
|
||||
|
||||
3. **User Satisfaction**
|
||||
- Users can perform core workflows without training
|
||||
- System performance < 500ms API response
|
||||
- Positive feedback from pilot users
|
||||
|
||||
4. **Business Value**
|
||||
- All applications registered in system
|
||||
- Deployment history accurate and complete
|
||||
- Users prefer LDPv2 over previous tools
|
||||
|
||||
---
|
||||
|
||||
## 🧪 Testing Strategy
|
||||
|
||||
### Backend Testing
|
||||
- **Unit Tests**: Service layer with Mockito (>80% coverage)
|
||||
- **Integration Tests**: Controllers with Testcontainers
|
||||
- **API Tests**: REST Assured or MockMvc
|
||||
|
||||
### Frontend Testing
|
||||
- **Unit Tests**: Components and services (>70% coverage)
|
||||
- **Integration Tests**: Component interactions
|
||||
- **E2E Tests**: Critical user flows with Cypress
|
||||
|
||||
---
|
||||
|
||||
## 📚 Key Documents
|
||||
|
||||
### For Project Managers
|
||||
- **00-MVP-OVERVIEW.md**: Scope, timeline, success criteria
|
||||
- **Stories/*.md**: Detailed requirements and acceptance criteria
|
||||
|
||||
### For Architects
|
||||
- **01-TECHNICAL-SETUP.md**: Architecture and tech stack
|
||||
- **data-model/complete-data-model.ts**: Complete data model
|
||||
- **api-specs/endpoint-summary.md**: API design
|
||||
|
||||
### For Developers
|
||||
- **stories/STORY-*.md**: Detailed implementation tasks
|
||||
- **01-TECHNICAL-SETUP.md**: Setup instructions
|
||||
- **api-specs/endpoint-summary.md**: API reference
|
||||
|
||||
### For QA/Testers
|
||||
- **stories/STORY-*.md**: Acceptance criteria and test scenarios
|
||||
- Each story contains detailed testing scenarios
|
||||
|
||||
---
|
||||
|
||||
## 🔄 Development Workflow
|
||||
|
||||
### For Each Story
|
||||
|
||||
1. **Read the story documentation** thoroughly
|
||||
2. **Setup environment** (if Story 0)
|
||||
3. **Backend Development**:
|
||||
- Create Liquibase migration
|
||||
- Implement JPA entities
|
||||
- Create repositories
|
||||
- Implement service layer
|
||||
- Create DTOs
|
||||
- Implement controllers
|
||||
- Write tests (unit + integration)
|
||||
4. **Frontend Development**:
|
||||
- Create TypeScript models
|
||||
- Implement Angular service
|
||||
- Create components (list, detail, form)
|
||||
- Add routing
|
||||
- Write tests (unit + E2E)
|
||||
5. **Review**: Code review, test review
|
||||
6. **Demo**: Demonstrate to stakeholders
|
||||
7. **Merge**: Merge to main branch
|
||||
8. **Document**: Update API docs, user docs
|
||||
|
||||
---
|
||||
|
||||
## 🐛 Known Limitations & Technical Debt
|
||||
|
||||
### MVP Limitations
|
||||
- Simple role-based authorization (will need environment-specific roles later)
|
||||
- Local authentication only (OAuth planned for Phase 2)
|
||||
- No deployment approval workflows
|
||||
- No automated notifications
|
||||
- No CI/CD integration
|
||||
|
||||
### Planned Improvements (Phase 2)
|
||||
- OAuth 2.0 integration (Azure AD, Okta)
|
||||
- Environment-specific user permissions
|
||||
- External dependencies tracking
|
||||
- SLA management
|
||||
- Automated deployment notifications
|
||||
- Integration with CI/CD pipelines
|
||||
- Advanced analytics and reporting
|
||||
|
||||
---
|
||||
|
||||
## 🤝 Contributing
|
||||
|
||||
### Code Standards
|
||||
- Follow Spring Boot conventions for backend
|
||||
- Follow Angular style guide for frontend
|
||||
- Write meaningful commit messages
|
||||
- Maintain test coverage thresholds
|
||||
- Document all public APIs
|
||||
|
||||
### Git Workflow
|
||||
1. Create feature branch: `feature/story-N-description`
|
||||
2. Commit frequently with clear messages
|
||||
3. Write/update tests
|
||||
4. Create pull request
|
||||
5. Address review comments
|
||||
6. Merge to main after approval
|
||||
|
||||
---
|
||||
|
||||
## 📞 Support & Questions
|
||||
|
||||
For questions about this package:
|
||||
- Review the relevant story documentation
|
||||
- Check the technical setup guide
|
||||
- Consult the API specification
|
||||
- Refer to the data model
|
||||
|
||||
---
|
||||
|
||||
## 📄 License
|
||||
|
||||
Proprietary - Internal use only
|
||||
|
||||
---
|
||||
|
||||
## 🎉 Let's Build!
|
||||
|
||||
You now have everything you need to build LDPv2 MVP successfully!
|
||||
|
||||
Start with Story 0 and follow the iterative approach. Good luck! 🚀
|
||||
|
||||
---
|
||||
|
||||
**Package Version**: 1.0
|
||||
**Last Updated**: February 2026
|
||||
**Status**: Ready for Development
|
||||
@@ -0,0 +1,308 @@
|
||||
# LDPv2 MVP - API Endpoints Summary
|
||||
|
||||
Complete list of RESTful API endpoints for the MVP.
|
||||
|
||||
**Base URL**: `http://localhost:8080/api`
|
||||
**Authentication**: Bearer JWT token (except /auth endpoints)
|
||||
|
||||
---
|
||||
|
||||
## Authentication Endpoints
|
||||
|
||||
| Method | Endpoint | Description | Auth Required |
|
||||
|--------|----------|-------------|---------------|
|
||||
| POST | `/auth/register` | Register new user | No |
|
||||
| POST | `/auth/login` | Login and get JWT token | No |
|
||||
| GET | `/auth/me` | Get current user info | Yes |
|
||||
|
||||
---
|
||||
|
||||
## Business Unit Endpoints
|
||||
|
||||
| Method | Endpoint | Description | Auth Required |
|
||||
|--------|----------|-------------|---------------|
|
||||
| GET | `/business-units` | List all business units | Yes |
|
||||
| GET | `/business-units/search?q={query}` | Search business units | Yes |
|
||||
| GET | `/business-units/{id}` | Get business unit by ID | Yes |
|
||||
| POST | `/business-units` | Create business unit | Yes |
|
||||
| PUT | `/business-units/{id}` | Update business unit | Yes |
|
||||
| DELETE | `/business-units/{id}` | Delete business unit | Yes |
|
||||
|
||||
**Query Parameters**:
|
||||
- `page`: Page number (default: 0)
|
||||
- `size`: Page size (default: 20)
|
||||
- `sort`: Sort criteria (e.g., `name,asc`)
|
||||
|
||||
---
|
||||
|
||||
## Application Endpoints
|
||||
|
||||
| Method | Endpoint | Description | Auth Required |
|
||||
|--------|----------|-------------|---------------|
|
||||
| GET | `/applications` | List all applications | Yes |
|
||||
| GET | `/applications/search` | Advanced search | Yes |
|
||||
| GET | `/applications/{id}` | Get application by ID | Yes |
|
||||
| POST | `/applications` | Create application | Yes |
|
||||
| PUT | `/applications/{id}` | Update application | Yes |
|
||||
| PATCH | `/applications/{id}/status` | Update status only | Yes |
|
||||
| DELETE | `/applications/{id}` | Delete application | Yes |
|
||||
| GET | `/applications/by-status/{status}` | Filter by status | Yes |
|
||||
| GET | `/applications/by-business-unit/{businessUnitId}` | Filter by BU | Yes |
|
||||
|
||||
**Query Parameters for `/applications` and `/applications/search`**:
|
||||
- `status`: Filter by ApplicationStatus
|
||||
- `businessUnitId`: Filter by business unit ID
|
||||
- `name`: Search by name (partial match)
|
||||
- `page`, `size`, `sort`: Pagination
|
||||
|
||||
---
|
||||
|
||||
## Environment Endpoints
|
||||
|
||||
| Method | Endpoint | Description | Auth Required |
|
||||
|--------|----------|-------------|---------------|
|
||||
| GET | `/environments` | List all environments | Yes |
|
||||
| GET | `/environments/{id}` | Get environment by ID | Yes |
|
||||
| POST | `/environments` | Create environment | Yes |
|
||||
| PUT | `/environments/{id}` | Update environment | Yes |
|
||||
| DELETE | `/environments/{id}` | Delete environment | Yes |
|
||||
| PATCH | `/environments/{id}/deactivate` | Deactivate environment | Yes |
|
||||
| PATCH | `/environments/{id}/reactivate` | Reactivate environment | Yes |
|
||||
|
||||
**Query Parameters**:
|
||||
- `isActive`: Filter by active status (default: true)
|
||||
- `isProduction`: Filter production environments
|
||||
- `environmentGroup`: Filter by group
|
||||
- `page`, `size`, `sort`: Pagination
|
||||
|
||||
---
|
||||
|
||||
## Version Endpoints
|
||||
|
||||
| Method | Endpoint | Description | Auth Required |
|
||||
|--------|----------|-------------|---------------|
|
||||
| GET | `/applications/{appId}/versions` | List versions for application | Yes |
|
||||
| GET | `/versions/{id}` | Get version by ID | Yes |
|
||||
| POST | `/applications/{appId}/versions` | Create version | Yes |
|
||||
| PUT | `/versions/{id}` | Update version | Yes |
|
||||
| DELETE | `/versions/{id}` | Delete version | Yes |
|
||||
| GET | `/versions/latest?applicationId={appId}` | Get latest version | Yes |
|
||||
|
||||
**Query Parameters for `/applications/{appId}/versions`**:
|
||||
- `page`, `size`, `sort`: Pagination (default sort: releaseDate,desc)
|
||||
|
||||
---
|
||||
|
||||
## Deployment Endpoints
|
||||
|
||||
### Recording & Retrieval
|
||||
|
||||
| Method | Endpoint | Description | Auth Required |
|
||||
|--------|----------|-------------|---------------|
|
||||
| POST | `/deployments` | Record new deployment | Yes |
|
||||
| GET | `/deployments` | List all deployments | Yes |
|
||||
| GET | `/deployments/{id}` | Get deployment by ID | Yes |
|
||||
| GET | `/deployments/search` | Advanced search | Yes |
|
||||
|
||||
### Current State Queries
|
||||
|
||||
| Method | Endpoint | Description | Auth Required |
|
||||
|--------|----------|-------------|---------------|
|
||||
| GET | `/deployments/current` | Get current state (all apps/envs) | Yes |
|
||||
| GET | `/applications/{appId}/deployments` | Deployment history for app | Yes |
|
||||
| GET | `/applications/{appId}/deployments/current` | Current state per env for app | Yes |
|
||||
| GET | `/environments/{envId}/deployments/current` | Current deployments in env | Yes |
|
||||
|
||||
### Statistics & Analytics
|
||||
|
||||
| Method | Endpoint | Description | Auth Required |
|
||||
|--------|----------|-------------|---------------|
|
||||
| GET | `/deployments/stats/summary` | Summary statistics | Yes |
|
||||
| GET | `/deployments/stats/frequency?range={days}` | Deployment frequency | Yes |
|
||||
| GET | `/deployments/stats/by-environment` | Deployments by environment | Yes |
|
||||
| GET | `/deployments/stats/by-application` | Top deployed applications | Yes |
|
||||
| GET | `/deployments/stats/version-distribution` | Version distribution | Yes |
|
||||
| GET | `/deployments/calendar?year={year}&month={month}` | Calendar data | Yes |
|
||||
|
||||
### Export
|
||||
|
||||
| Method | Endpoint | Description | Auth Required |
|
||||
|--------|----------|-------------|---------------|
|
||||
| GET | `/deployments/export?format={csv\|excel}` | Export deployments | Yes |
|
||||
|
||||
**Query Parameters for `/deployments` and `/deployments/search`**:
|
||||
- `applicationId`: Filter by application
|
||||
- `versionId`: Filter by version
|
||||
- `environmentId`: Filter by environment
|
||||
- `dateFrom`: Filter by start date
|
||||
- `dateTo`: Filter by end date
|
||||
- `deployedBy`: Filter by user
|
||||
- `page`, `size`, `sort`: Pagination
|
||||
|
||||
**Query Parameters for `/deployments/current`**:
|
||||
- `applicationId`: Optional filter by application
|
||||
- `environmentId`: Optional filter by environment
|
||||
|
||||
---
|
||||
|
||||
## Contact Endpoints
|
||||
|
||||
### Contact Roles
|
||||
|
||||
| Method | Endpoint | Description | Auth Required |
|
||||
|--------|----------|-------------|---------------|
|
||||
| GET | `/contact-roles` | List all contact roles | Yes |
|
||||
| POST | `/contact-roles` | Create contact role | Yes (Admin) |
|
||||
|
||||
### Persons
|
||||
|
||||
| Method | Endpoint | Description | Auth Required |
|
||||
|--------|----------|-------------|---------------|
|
||||
| GET | `/persons` | List all persons | Yes |
|
||||
| GET | `/persons/{id}` | Get person by ID | Yes |
|
||||
| POST | `/persons` | Create person | Yes |
|
||||
| PUT | `/persons/{id}` | Update person | Yes |
|
||||
| DELETE | `/persons/{id}` | Delete person | Yes |
|
||||
|
||||
**Query Parameters for `/persons`**:
|
||||
- `email`: Search by email
|
||||
- `name`: Search by name (first or last)
|
||||
- `page`, `size`, `sort`: Pagination
|
||||
|
||||
### Contacts
|
||||
|
||||
| Method | Endpoint | Description | Auth Required |
|
||||
|--------|----------|-------------|---------------|
|
||||
| GET | `/contacts` | List all contacts | Yes |
|
||||
| GET | `/contacts/{id}` | Get contact with persons | Yes |
|
||||
| POST | `/contacts` | Create contact | Yes |
|
||||
| PUT | `/contacts/{id}` | Update contact | Yes |
|
||||
| DELETE | `/contacts/{id}` | Delete contact | Yes |
|
||||
| POST | `/contacts/{id}/persons/{personId}` | Add person to contact | Yes |
|
||||
| DELETE | `/contacts/{id}/persons/{personId}` | Remove person from contact | Yes |
|
||||
| PATCH | `/contacts/{id}/persons/{personId}/primary` | Set as primary | Yes |
|
||||
|
||||
---
|
||||
|
||||
## Common Response Formats
|
||||
|
||||
### Success Response (Single Entity)
|
||||
```json
|
||||
{
|
||||
"id": "uuid",
|
||||
"name": "Entity Name",
|
||||
...
|
||||
"createdAt": "2026-02-07T10:00:00Z",
|
||||
"updatedAt": "2026-02-07T10:00:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
### Success Response (Paginated List)
|
||||
```json
|
||||
{
|
||||
"content": [ /* array of entities */ ],
|
||||
"pageable": {
|
||||
"pageNumber": 0,
|
||||
"pageSize": 20,
|
||||
"sort": { "sorted": true, "unsorted": false }
|
||||
},
|
||||
"totalElements": 100,
|
||||
"totalPages": 5,
|
||||
"last": false,
|
||||
"first": true,
|
||||
"size": 20,
|
||||
"number": 0,
|
||||
"numberOfElements": 20,
|
||||
"empty": false
|
||||
}
|
||||
```
|
||||
|
||||
### Error Response
|
||||
```json
|
||||
{
|
||||
"status": 400,
|
||||
"message": "Validation failed",
|
||||
"timestamp": "2026-02-07T10:00:00Z",
|
||||
"path": "/api/applications",
|
||||
"errors": [
|
||||
{
|
||||
"field": "name",
|
||||
"message": "Name is required",
|
||||
"rejectedValue": null
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## HTTP Status Codes
|
||||
|
||||
| Code | Meaning | When Used |
|
||||
|------|---------|-----------|
|
||||
| 200 | OK | Successful GET, PUT, PATCH |
|
||||
| 201 | Created | Successful POST |
|
||||
| 204 | No Content | Successful DELETE |
|
||||
| 400 | Bad Request | Validation error, business rule violation |
|
||||
| 401 | Unauthorized | Missing or invalid JWT token |
|
||||
| 403 | Forbidden | Valid token but insufficient permissions |
|
||||
| 404 | Not Found | Resource doesn't exist |
|
||||
| 409 | Conflict | Duplicate resource (e.g., unique constraint violation) |
|
||||
| 500 | Internal Server Error | Unexpected server error |
|
||||
|
||||
---
|
||||
|
||||
## Authentication Header
|
||||
|
||||
All authenticated endpoints require:
|
||||
```
|
||||
Authorization: Bearer <JWT_TOKEN>
|
||||
```
|
||||
|
||||
Example:
|
||||
```
|
||||
GET /api/applications
|
||||
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## CORS Configuration
|
||||
|
||||
Frontend origin allowed: `http://localhost:4200` (development)
|
||||
|
||||
Allowed methods: `GET`, `POST`, `PUT`, `PATCH`, `DELETE`, `OPTIONS`
|
||||
|
||||
Allowed headers: `*`
|
||||
|
||||
Credentials: `true`
|
||||
|
||||
---
|
||||
|
||||
## Rate Limiting (Future)
|
||||
|
||||
Not implemented in MVP, but planned for production:
|
||||
- 100 requests per minute per user
|
||||
- 1000 requests per hour per user
|
||||
|
||||
---
|
||||
|
||||
## API Versioning
|
||||
|
||||
Current version: `v1` (implicit)
|
||||
|
||||
Future versions will use URL path: `/api/v2/...`
|
||||
|
||||
---
|
||||
|
||||
## OpenAPI/Swagger Documentation
|
||||
|
||||
Interactive API documentation available at:
|
||||
- **Swagger UI**: `http://localhost:8080/swagger-ui/index.html`
|
||||
- **OpenAPI Spec**: `http://localhost:8080/v3/api-docs`
|
||||
|
||||
---
|
||||
|
||||
**Document Version**: 1.0
|
||||
**Last Updated**: February 2026
|
||||
**Status**: Complete for MVP
|
||||
@@ -0,0 +1,478 @@
|
||||
# LDPv2 - Complete Data Model (TypeScript)
|
||||
|
||||
This file contains all TypeScript interfaces and enums for the LDPv2 MVP.
|
||||
|
||||
## Enums
|
||||
|
||||
```typescript
|
||||
// Application lifecycle status
|
||||
export enum ApplicationStatus {
|
||||
IDEA = 'IDEA',
|
||||
IN_DEVELOPMENT = 'IN_DEVELOPMENT',
|
||||
IN_SERVICE = 'IN_SERVICE',
|
||||
MAINTENANCE = 'MAINTENANCE',
|
||||
DECOMMISSIONED = 'DECOMMISSIONED'
|
||||
}
|
||||
|
||||
// External dependency types (Phase 2)
|
||||
export enum ExternalDependencyType {
|
||||
WEB_SERVICE = 'WEB_SERVICE',
|
||||
DATABASE = 'DATABASE',
|
||||
CERTIFICATE = 'CERTIFICATE',
|
||||
NETWORK_FLOW = 'NETWORK_FLOW'
|
||||
}
|
||||
|
||||
// Day of week for maintenance windows (Phase 2)
|
||||
export enum DayOfWeek {
|
||||
MONDAY = 'MONDAY',
|
||||
TUESDAY = 'TUESDAY',
|
||||
WEDNESDAY = 'WEDNESDAY',
|
||||
THURSDAY = 'THURSDAY',
|
||||
FRIDAY = 'FRIDAY',
|
||||
SATURDAY = 'SATURDAY',
|
||||
SUNDAY = 'SUNDAY'
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Core Entities
|
||||
|
||||
### Business Unit
|
||||
|
||||
```typescript
|
||||
export interface BusinessUnit {
|
||||
id: string;
|
||||
name: string;
|
||||
description?: string;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
}
|
||||
|
||||
export interface CreateBusinessUnitRequest {
|
||||
name: string;
|
||||
description?: string;
|
||||
}
|
||||
|
||||
export interface UpdateBusinessUnitRequest {
|
||||
name?: string;
|
||||
description?: string;
|
||||
}
|
||||
|
||||
export interface BusinessUnitSummary {
|
||||
id: string;
|
||||
name: string;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Application
|
||||
|
||||
```typescript
|
||||
export interface Application {
|
||||
id: string;
|
||||
name: string;
|
||||
description?: string;
|
||||
status: ApplicationStatus;
|
||||
businessUnit: BusinessUnitSummary;
|
||||
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;
|
||||
}
|
||||
|
||||
export interface ApplicationSummary {
|
||||
id: string;
|
||||
name: string;
|
||||
status: ApplicationStatus;
|
||||
businessUnitName: string;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Environment
|
||||
|
||||
```typescript
|
||||
export interface Environment {
|
||||
id: string;
|
||||
name: string;
|
||||
description?: string;
|
||||
isProduction: boolean;
|
||||
criticalityLevel?: number; // 1-5
|
||||
isActive: boolean;
|
||||
environmentGroup?: string;
|
||||
tags?: string;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
}
|
||||
|
||||
export interface CreateEnvironmentRequest {
|
||||
name: string;
|
||||
description?: string;
|
||||
isProduction: boolean;
|
||||
criticalityLevel?: number;
|
||||
environmentGroup?: string;
|
||||
tags?: string;
|
||||
}
|
||||
|
||||
export interface UpdateEnvironmentRequest {
|
||||
name?: string;
|
||||
description?: string;
|
||||
isProduction?: boolean;
|
||||
criticalityLevel?: number;
|
||||
isActive?: boolean;
|
||||
environmentGroup?: string;
|
||||
tags?: string;
|
||||
}
|
||||
|
||||
export interface EnvironmentSummary {
|
||||
id: string;
|
||||
name: string;
|
||||
isProduction: boolean;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Version
|
||||
|
||||
```typescript
|
||||
export interface Version {
|
||||
id: string;
|
||||
applicationId: string;
|
||||
versionIdentifier: string; // "1.2.3", "2024.Q1"
|
||||
externalReference?: string; // Git tag, JIRA link
|
||||
releaseDate: Date;
|
||||
endOfLifeDate?: Date;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
}
|
||||
|
||||
export interface CreateVersionRequest {
|
||||
versionIdentifier: string;
|
||||
externalReference?: string;
|
||||
releaseDate: Date;
|
||||
endOfLifeDate?: Date;
|
||||
}
|
||||
|
||||
export interface UpdateVersionRequest {
|
||||
versionIdentifier?: string;
|
||||
externalReference?: string;
|
||||
releaseDate?: Date;
|
||||
endOfLifeDate?: Date;
|
||||
}
|
||||
|
||||
export interface VersionSummary {
|
||||
id: string;
|
||||
versionIdentifier: string;
|
||||
releaseDate: Date;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Deployment
|
||||
|
||||
```typescript
|
||||
export interface Deployment {
|
||||
id: string;
|
||||
application: ApplicationSummary;
|
||||
version: VersionSummary;
|
||||
environment: EnvironmentSummary;
|
||||
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: ApplicationSummary;
|
||||
environment: EnvironmentSummary;
|
||||
version: VersionSummary;
|
||||
deploymentDate: Date;
|
||||
deployedBy?: string;
|
||||
}
|
||||
|
||||
export interface DeploymentSearchCriteria {
|
||||
applicationId?: string;
|
||||
applicationName?: string;
|
||||
versionId?: string;
|
||||
environmentIds?: string[];
|
||||
dateFrom?: Date;
|
||||
dateTo?: Date;
|
||||
deployedBy?: string;
|
||||
notes?: string;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Contact Management
|
||||
|
||||
```typescript
|
||||
export interface ContactRole {
|
||||
id: string;
|
||||
roleName: string;
|
||||
description?: string;
|
||||
}
|
||||
|
||||
export interface Person {
|
||||
id: string;
|
||||
firstName: string;
|
||||
lastName: string;
|
||||
email: string;
|
||||
phone?: string;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
}
|
||||
|
||||
export interface CreatePersonRequest {
|
||||
firstName: string;
|
||||
lastName: string;
|
||||
email: string;
|
||||
phone?: string;
|
||||
}
|
||||
|
||||
export interface UpdatePersonRequest {
|
||||
firstName?: string;
|
||||
lastName?: string;
|
||||
email?: string;
|
||||
phone?: string;
|
||||
}
|
||||
|
||||
export interface Contact {
|
||||
id: string;
|
||||
contactRole: ContactRole;
|
||||
persons: PersonInContact[];
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
}
|
||||
|
||||
export interface PersonInContact {
|
||||
person: Person;
|
||||
isPrimary: boolean;
|
||||
}
|
||||
|
||||
export interface CreateContactRequest {
|
||||
contactRoleId: string;
|
||||
personIds: string[];
|
||||
primaryPersonId: string;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### User & Authentication
|
||||
|
||||
```typescript
|
||||
export interface User {
|
||||
id: string;
|
||||
username: string;
|
||||
email: string;
|
||||
role: string; // "ADMIN", "USER"
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
}
|
||||
|
||||
export interface LoginRequest {
|
||||
username: string;
|
||||
password: string;
|
||||
}
|
||||
|
||||
export interface LoginResponse {
|
||||
token: string;
|
||||
user: User;
|
||||
}
|
||||
|
||||
export interface RegisterRequest {
|
||||
username: string;
|
||||
email: string;
|
||||
password: string;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Statistics & Analytics
|
||||
|
||||
```typescript
|
||||
export interface DeploymentSummary {
|
||||
totalApplications: number;
|
||||
totalDeployments: number;
|
||||
deploymentsThisWeek: number;
|
||||
deploymentsThisMonth: number;
|
||||
productionDeployments: number;
|
||||
}
|
||||
|
||||
export interface DeploymentFrequency {
|
||||
date: string; // "2026-02-01"
|
||||
count: number;
|
||||
}
|
||||
|
||||
export interface EnvironmentStats {
|
||||
environmentName: string;
|
||||
deploymentCount: number;
|
||||
}
|
||||
|
||||
export interface ApplicationStats {
|
||||
applicationName: string;
|
||||
deploymentCount: number;
|
||||
}
|
||||
|
||||
export interface VersionDistribution {
|
||||
versionIdentifier: string;
|
||||
environmentCount: number;
|
||||
environments: string[];
|
||||
}
|
||||
|
||||
export interface CalendarData {
|
||||
date: string; // "2026-02-01"
|
||||
deploymentCount: number;
|
||||
activityLevel: 'low' | 'normal' | 'high' | 'none';
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Pagination & Sorting
|
||||
|
||||
```typescript
|
||||
export interface Pageable {
|
||||
pageNumber: number;
|
||||
pageSize: number;
|
||||
sort: Sort;
|
||||
}
|
||||
|
||||
export interface Sort {
|
||||
sorted: boolean;
|
||||
unsorted: boolean;
|
||||
orders?: SortOrder[];
|
||||
}
|
||||
|
||||
export interface SortOrder {
|
||||
property: string;
|
||||
direction: 'ASC' | 'DESC';
|
||||
}
|
||||
|
||||
export interface Page<T> {
|
||||
content: T[];
|
||||
pageable: Pageable;
|
||||
totalElements: number;
|
||||
totalPages: number;
|
||||
last: boolean;
|
||||
first: boolean;
|
||||
size: number;
|
||||
number: number;
|
||||
numberOfElements: number;
|
||||
empty: boolean;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Error Handling
|
||||
|
||||
```typescript
|
||||
export interface ApiError {
|
||||
status: number;
|
||||
message: string;
|
||||
timestamp: Date;
|
||||
path?: string;
|
||||
errors?: FieldError[];
|
||||
}
|
||||
|
||||
export interface FieldError {
|
||||
field: string;
|
||||
message: string;
|
||||
rejectedValue?: any;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Future Entities (Phase 2)
|
||||
|
||||
These are not part of the MVP but are included for completeness:
|
||||
|
||||
```typescript
|
||||
// External Dependencies (Phase 2)
|
||||
export interface ExternalDependency {
|
||||
id: string;
|
||||
applicationId: string;
|
||||
dependencyType: ExternalDependencyType;
|
||||
name: string;
|
||||
description?: string;
|
||||
documentation?: string;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
}
|
||||
|
||||
// Data Usage Agreements (Phase 2)
|
||||
export interface DataUsageAgreement {
|
||||
id: string;
|
||||
dataNature: string;
|
||||
documentationUrl: string;
|
||||
startDate: Date;
|
||||
endDate?: Date;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
}
|
||||
|
||||
// SLA (Phase 2)
|
||||
export interface SLA {
|
||||
id: string;
|
||||
availabilityPercentage: number;
|
||||
minAvgResponseTimeSeconds: number;
|
||||
reactionTime: string;
|
||||
diagramJson?: object;
|
||||
dependenciesDescription?: string;
|
||||
responsibilityScope?: string;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
}
|
||||
|
||||
// Technical Documentation (Phase 2)
|
||||
export interface TechnicalDocumentation {
|
||||
id: string;
|
||||
applicationId: string;
|
||||
title: string;
|
||||
url: string;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**File Version**: 1.0
|
||||
**Last Updated**: February 2026
|
||||
**Status**: Complete for MVP
|
||||
@@ -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