Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
121 changes: 121 additions & 0 deletions .github/modernize/assessment/engines/api-service-contracts.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
# API & Service Communication Contracts

PhotoAlbum-Java exposes **5 HTTP endpoints** across three Spring MVC controllers; all communication is synchronous REST over HTTP with no API gateway, message broker, or external service integrations.

## Service Catalog

| Service | Port | Category | Purpose |
|---------|------|----------|---------|
| photoalbum-java-app | 8080 | Business | Spring Boot web application serving the photo gallery UI and REST upload API |
| oracle-db | 1521 | Infrastructure | Oracle Database Free (third-party container) providing persistent BLOB and metadata storage |

## API Endpoints Inventory

| Service | Method | Path | Request Type | Response Type |
|---------|--------|------|-------------|--------------|
| HomeController | GET | `/` | — | HTML view (`index.html`) with `List<Photo>` model |
| HomeController | POST | `/upload` | `multipart/form-data` — `files` param (`List<MultipartFile>`) | JSON `200 OK` — `{success, uploadedPhotos[], failedUploads[]}` or `400 Bad Request` |
| DetailController | GET | `/detail/{id}` | Path param `id` (String UUID) | HTML view (`detail.html`) with `Photo` model + nav IDs; redirects to `/` on not-found |
| DetailController | POST | `/detail/{id}/delete` | Path param `id` (String UUID) | Redirect `302` to `/` with flash attributes |
| PhotoFileController | GET | `/photo/{id}` | Path param `id` (String UUID) | Binary image response (`image/jpeg`, `image/png`, etc.) with `Cache-Control: no-store` headers; `404` if not found |

## Management & Observability Endpoints

| Service | Endpoint | Custom Metrics |
|---------|----------|---------------|
| photoalbum-java-app | None — Spring Boot Actuator is not on the classpath | None declared |

No `/actuator/health`, `/actuator/metrics`, or `/actuator/prometheus` endpoints are available. There are no `@Timed` or custom Micrometer metric registrations in the codebase.

## DTOs & Contracts

**Service-level domain classes used in the API:**

- **`Photo`** (JPA Entity / response model): Returned directly from service layer to controllers and rendered in Thymeleaf templates or serialized to JSON in the upload response. Not immutable — uses standard mutable POJO with getters/setters. Full field details are in `data-architecture.md`.
- **`UploadResult`** (response DTO): Carries the outcome of a single-file upload operation: `success` (boolean), `fileName` (String), `photoId` (String UUID on success), and `errorMessage` (String on failure). Mutable POJO; provides a `failure(...)` static factory method. Consumed by `HomeController` to build the JSON upload response.

No OpenAPI/Swagger specification, protobuf schemas, or GraphQL schemas are present. Jackson (via `spring-boot-starter-json`) handles JSON serialization for the upload response endpoint using default settings — no custom serializers or `ObjectMapper` configuration is declared.

## Communication Patterns

**Synchronous only.** All client-to-application communication is HTTP/1.1 REST. The application makes no outbound HTTP calls to other services; all downstream communication is via JDBC to Oracle.

**Resilience:** No circuit breaker, retry policy, bulkhead, or timeout configuration is declared (no Resilience4j, Spring Retry, or equivalent). Failed database operations propagate as unchecked `RuntimeException` to the controller, which returns a `500` response or redirects to the home page.

**Service discovery:** Not applicable — single-service deployment. The Oracle JDBC URL is hardcoded in `application.properties` (default profile) and overridden via environment variable `SPRING_DATASOURCE_URL` in the Docker profile.

**Startup dependency chain:** The `docker-compose.yml` configures `photoalbum-java-app` to wait for `oracle-db` to pass its health check (`condition: service_healthy`) before starting. No application-level readiness probe is registered. For full Docker configuration details see `configuration-inventory.md`.

**Security posture:** No authentication, authorization, or TLS is configured. Spring Security is not on the classpath. All five endpoints — including photo deletion (`POST /detail/{id}/delete`) and file upload (`POST /upload`) — are publicly accessible with no authorization checks. There is no CSRF protection and no HTTPS configuration.

## Service Technology Matrix

| Service | Web Framework | Data Access | Discovery | Gateway | Actuator/Health | Cache | Metrics |
|---------|--------------|-------------|-----------|---------|----------------|-------|---------|
| photoalbum-java-app | Spring MVC (servlet) | Spring Data JPA + Hibernate 5.6 | None | None | None | None | None |
| oracle-db | N/A (third-party) | N/A | N/A | N/A | Docker healthcheck only | N/A | N/A |

## Service Communication Sequence

```mermaid
sequenceDiagram
participant Client as "Browser / HTTP Client"
participant HomeCtrl as "HomeController"
participant DetailCtrl as "DetailController"
participant FileCtrl as "PhotoFileController"
participant PhotoSvc as "PhotoServiceImpl"
participant Repo as "PhotoRepository"
participant DB as "Oracle Database"

Note over Client,DB: Gallery page load
Client->>HomeCtrl: GET /
HomeCtrl->>PhotoSvc: getAllPhotos()
PhotoSvc->>Repo: findAllOrderByUploadedAtDesc()
Repo->>DB: SELECT ... FROM PHOTOS ORDER BY UPLOADED_AT DESC
DB-->>Repo: List of Photo rows
Repo-->>PhotoSvc: List<Photo>
PhotoSvc-->>HomeCtrl: List<Photo>
HomeCtrl-->>Client: 200 HTML (index.html, photo grid)

Note over Client,DB: Photo upload
Client->>HomeCtrl: POST /upload (multipart files)
loop For each file
HomeCtrl->>PhotoSvc: uploadPhoto(MultipartFile)
PhotoSvc->>PhotoSvc: Validate MIME type and size
alt Validation fails
PhotoSvc-->>HomeCtrl: UploadResult(success=false, error)
else Validation passes
PhotoSvc->>Repo: save(Photo with BLOB data)
Repo->>DB: INSERT INTO PHOTOS (... photo_data BLOB ...)
DB-->>Repo: saved Photo
Repo-->>PhotoSvc: Photo
PhotoSvc-->>HomeCtrl: UploadResult(success=true, photoId)
end
end
HomeCtrl-->>Client: 200 JSON {success, uploadedPhotos[], failedUploads[]}

Note over Client,DB: Serve photo binary
Client->>FileCtrl: GET /photo/{id}
FileCtrl->>PhotoSvc: getPhotoById(id)
PhotoSvc->>Repo: findById(id)
Repo->>DB: SELECT ... FROM PHOTOS WHERE ID = ?
DB-->>Repo: Photo row with BLOB
Repo-->>PhotoSvc: Optional<Photo>
alt Photo found
PhotoSvc-->>FileCtrl: Optional.of(Photo)
FileCtrl-->>Client: 200 image/jpeg (binary BLOB data, no-cache headers)
else Not found
PhotoSvc-->>FileCtrl: Optional.empty()
FileCtrl-->>Client: 404 Not Found
end

Note over Client,DB: Delete photo
Client->>DetailCtrl: POST /detail/{id}/delete
DetailCtrl->>PhotoSvc: deletePhoto(id)
PhotoSvc->>Repo: delete(Photo)
Repo->>DB: DELETE FROM PHOTOS WHERE ID = ?
DB-->>Repo: OK
Repo-->>PhotoSvc: void
PhotoSvc-->>DetailCtrl: true
DetailCtrl-->>Client: 302 Redirect to /
```
96 changes: 96 additions & 0 deletions .github/modernize/assessment/engines/architecture-diagram.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
# Architecture Diagram

PhotoAlbum-Java is a Spring Boot 2.7 web application that allows users to upload, browse, and manage photos, storing image data as BLOBs in an Oracle database.

## Application Architecture

```mermaid
flowchart TD
subgraph Client["Client Layer"]
Browser["Web Browser"]
end
subgraph App["Application Layer - Spring Boot 2.7 / Java 8"]
Web["Spring MVC Controllers\n(HomeController, DetailController,\nPhotoFileController)"]
Template["Thymeleaf Templates\n(index, detail, layout)"]
Service["Business Services\n(PhotoServiceImpl)"]
Validation["Bean Validation\n(Spring Validator)"]
end
subgraph Data["Data Layer"]
JPA["Spring Data JPA\n(PhotoRepository)"]
DB[("Oracle Database\n(FREEPDB1 / BLOB storage)")]
end

Browser -->|"HTTP GET / POST"| Web
Web -->|"renders"| Template
Web -->|"delegates"| Service
Service -->|"validates"| Validation
Service -->|"CRUD + native queries"| JPA
JPA -->|"JDBC / ojdbc8"| DB
```

### Technology Stack Summary

| Layer | Technology | Version | Purpose |
|-------|-----------|---------|---------|
| Presentation | Spring MVC + Thymeleaf | 2.7.18 / 3.x | Server-side rendering and REST endpoints |
| Business Logic | Spring Boot Service | 2.7.18 | Photo upload, retrieval, deletion, navigation |
| Data Access | Spring Data JPA / Hibernate | 2.7.18 | ORM and query abstraction |
| Database | Oracle Database (FREEPDB1) | Oracle XE / Free | Persistent storage for photo metadata and BLOBs |
| Runtime | Java | 8 | Application runtime |
| Build | Apache Maven | 3.x | Dependency management and build |
| Testing | JUnit 5 + H2 | Spring Boot 2.7.18 | Unit and integration tests |

### Data Storage & External Services

Photos and their metadata (filename, MIME type, dimensions, upload timestamp) are stored entirely within an Oracle Database instance. The binary image content is persisted as a `BLOB` (`byte[]` mapped via `@Lob`) in the `photos` table, eliminating the need for a file system or external object store. The application connects to Oracle via the `ojdbc8` JDBC driver using a fixed data source configured in `application.properties`. No external caches, message brokers, or third-party APIs are used; all data flows are internal between the Spring Boot process and the Oracle instance.

### Key Architectural Decisions

- **BLOB storage in Oracle**: Images are stored directly in the database as byte arrays rather than on disk or in cloud object storage, simplifying deployment but coupling the app tightly to Oracle.
- **Native SQL queries for Oracle-specific features**: The `PhotoRepository` uses Oracle-specific functions (`ROWNUM`, `TO_CHAR`, `NVL`, analytical `RANK() OVER`) in native queries to implement pagination, filtering, and ranking.
- **Constructor injection + `@Transactional` service**: `PhotoServiceImpl` receives all dependencies via constructor and is annotated `@Transactional`, following standard Spring best practices for testability and transaction management.

## Component Relationships

```mermaid
flowchart LR
subgraph Presentation["Presentation Layer"]
HomeCtrl["HomeController"]
DetailCtrl["DetailController"]
PhotoFileCtrl["PhotoFileController"]
end
subgraph Business["Business Logic Layer"]
PhotoSvc["PhotoService (interface)"]
PhotoSvcImpl["PhotoServiceImpl"]
end
subgraph DataAccess["Data Access Layer"]
PhotoRepo["PhotoRepository\n(JpaRepository)"]
end
subgraph Model["Domain Model"]
PhotoEntity["Photo (JPA Entity)"]
UploadResult["UploadResult (DTO)"]
end

HomeCtrl -->|"delegates upload/list"| PhotoSvc
DetailCtrl -->|"delegates view/delete/nav"| PhotoSvc
PhotoFileCtrl -->|"delegates file serve"| PhotoSvc
PhotoSvc -.->|"implemented by"| PhotoSvcImpl
PhotoSvcImpl -->|"queries/saves"| PhotoRepo
PhotoRepo -->|"maps to/from"| PhotoEntity
PhotoSvcImpl -->|"produces"| UploadResult
HomeCtrl -->|"returns"| UploadResult
```

### Component Inventory

| Component | Layer | Type | Responsibility |
|-----------|-------|------|---------------|
| HomeController | Presentation | Spring MVC Controller | Handles GET `/` (gallery list) and POST `/upload` (multi-file upload); returns HTML view or JSON |
| DetailController | Presentation | Spring MVC Controller | Handles GET `/detail/{id}` (single photo view) and POST `/detail/{id}/delete` (photo deletion) |
| PhotoFileController | Presentation | Spring MVC Controller | Handles GET `/photo/{id}` to stream BLOB photo data with appropriate `Content-Type` headers |
| PhotoService | Business Logic | Service Interface | Defines contract for all photo operations (list, get, upload, delete, navigation) |
| PhotoServiceImpl | Business Logic | Service Implementation | Validates files (MIME type, size), reads bytes, extracts dimensions via `ImageIO`, persists via repository |
| PhotoRepository | Data Access | Spring Data JPA Repository | Extends `JpaRepository`; provides CRUD plus Oracle-specific native queries for ordering, pagination, and statistics |
| Photo | Domain Model | JPA Entity | Maps to `photos` table; holds metadata and `@Lob` binary image data |
| UploadResult | Domain Model | DTO | Carries upload outcome (success flag, photo ID or error message) between service and controller |
| MathUtil | Utility | Utility Class | General-purpose math helper utilities |
Loading