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
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# API & Service Communication Contracts

The application exposes a small HTTP surface made up of one gallery page, one upload endpoint, one image streaming endpoint, and detail/delete routes for individual photos. Communication is entirely synchronous: browser requests are handled by Spring MVC controllers, which call a local service and persist to Oracle through JPA.

## Service Catalog

| Service | Port | Category | Purpose |
|---|---:|---|---|
| `photoalbum-java-app` | 8080 | API Layer | Serves gallery/detail pages, accepts uploads, streams photo content, and deletes photos |
| `oracle-db` | 1521 | Infrastructure | Stores photo metadata and image BLOB data for the web application |

## API Endpoints Inventory

| Service | Method | Path | Request Type | Response Type |
|---|---|---|---|---|
| `photoalbum-java-app` | GET | `/` | None | Thymeleaf `index.html` view with `photos` model data |
| `photoalbum-java-app` | POST | `/upload` | Multipart form field `files` containing one or more `MultipartFile` objects | JSON `Map<String,Object>` with `success`, `uploadedPhotos`, and `failedUploads` |
| `photoalbum-java-app` | GET | `/detail/{id}` | Path parameter `id:String` | Thymeleaf `detail.html` view or redirect to `/` when not found |
| `photoalbum-java-app` | POST | `/detail/{id}/delete` | Path parameter `id:String` | Redirect to `/` with flash success/error message |
| `photoalbum-java-app` | GET | `/photo/{id}` | Path parameter `id:String` | `ResponseEntity<Resource>` image stream with 200, 404, or 500 status |

## Management & Observability Endpoints

| Service | Endpoint | Custom Metrics |
|---|---|---|
| `photoalbum-java-app` | None detected | No Actuator, health, metrics, or Swagger endpoints detected |

## DTOs & Contracts

The application does not define dedicated request DTO classes for its HTTP surface. Upload requests are accepted as Spring `MultipartFile` collections, while server-rendered views bind directly to the `Photo` domain entity for display purposes. The only explicit contract helper class is `UploadResult`, which is used internally by the service layer to communicate per-file outcomes before the controller converts those results into an ad hoc JSON map.

No gateway-level aggregation DTOs, OpenAPI specifications, protobuf schemas, or GraphQL schemas were found. JSON serialization relies on Spring Boot's default Jackson configuration through `spring-boot-starter-json`.

## Communication Patterns

All communication is synchronous. Browser clients call Spring MVC controllers over HTTP, controllers invoke `PhotoServiceImpl` through direct in-process method calls, and the service uses `PhotoRepository` for synchronous Oracle database access. No asynchronous messaging, background workers, service discovery, API gateway, client-side load balancing, retry policy, circuit breaker, or timeout library was detected.

API availability depends on the Oracle database container being healthy before the web container starts; Docker Compose enforces this startup dependency with `depends_on` and a database health check. Security posture is minimal: no TLS termination, authentication, authorization rules, or Spring Security configuration were found, so all endpoints are publicly accessible within the deployment environment.

## Service Technology Matrix

| Service | Web | Data Access | Discovery | Gateway | Actuator | Cache | Metrics |
|---|---|---|---|---|---|---|---|
| `photoalbum-java-app` | Spring MVC + Thymeleaf | Spring Data JPA / Hibernate | None | None | None | None | None |
| `oracle-db` | N/A | Oracle database engine | None | None | Health check only | N/A | None |

## Service Communication Sequence

```mermaid
sequenceDiagram
participant Browser
participant Home as "HomeController"
participant Service as "PhotoServiceImpl"
participant Repo as "PhotoRepository"
participant DB as "Oracle Database"

Browser->>Home: POST /upload (multipart files)
Home->>Service: uploadPhoto(file)
alt File passes validation
Service->>Service: Validate MIME type and size
Service->>Service: Read bytes and image dimensions
Service->>Repo: save(Photo)
Repo->>DB: INSERT photo metadata and BLOB
DB-->>Repo: Stored row
Repo-->>Service: Persisted Photo
Home->>Service: getPhotoById(photoId)
Service->>Repo: findById(photoId)
Repo->>DB: SELECT photo by id
DB-->>Repo: Photo row
Repo-->>Service: Photo
Service-->>Home: Upload success result
Home-->>Browser: 200 JSON with uploadedPhotos
else Validation or persistence failure
Service-->>Home: UploadResult failure
Home-->>Browser: 200 JSON with failedUploads or 400 for missing files
end
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
# Architecture Diagram

This document summarizes the Photo Album application's runtime structure and the main component relationships that support photo upload, gallery browsing, image retrieval, and deletion.

## Application Architecture

```mermaid
flowchart TD
subgraph Client["Client Layer"]
Browser["Web Browser"]
end

subgraph App["Application Layer - Spring Boot 2.7"]
Views["Thymeleaf Views"]
UploadJs["Upload JavaScript"]
HomeCtrl["HomeController"]
DetailCtrl["DetailController"]
FileCtrl["PhotoFileController"]
PhotoSvc["PhotoServiceImpl"]
end

subgraph Data["Data Layer"]
PhotoRepo["Spring Data JPA Repository"]
OracleDB[("Oracle Database PHOTOS table")]
end

subgraph External["External Services"]
BootstrapCdn["Bootstrap CDN"]
OracleContainer["Oracle DB Container"]
end

Browser -->|"Loads gallery and detail pages"| Views
Browser -->|"Drag and drop uploads"| UploadJs
Views -->|"GET / and GET /detail/{id}"| HomeCtrl
Views -->|"Photo detail navigation and delete"| DetailCtrl
UploadJs -->|"POST /upload"| HomeCtrl
Browser -->|"GET /photo/{id}"| FileCtrl
HomeCtrl -->|"List and create photo records"| PhotoSvc
DetailCtrl -->|"Lookup, navigate, delete"| PhotoSvc
FileCtrl -->|"Load BLOB content"| PhotoSvc
PhotoSvc -->|"CRUD and custom queries"| PhotoRepo
PhotoRepo -->|"SQL and BLOB persistence"| OracleDB
OracleContainer -->|"Hosts"| OracleDB
Browser -->|"Fetches UI assets"| BootstrapCdn
```

### Technology Stack Summary

| Layer | Technology | Version | Purpose |
|---|---|---|---|
| Presentation | Thymeleaf templates, Bootstrap, vanilla JavaScript | Thymeleaf via Spring Boot 2.7.18, Bootstrap 5.3.0 | Renders gallery/detail pages and handles drag-and-drop uploads |
| Web | Spring Boot Web, Spring MVC | 2.7.18 | Handles HTTP requests and server-side page composition |
| Business Logic | PhotoServiceImpl | Application code | Validates uploads, extracts metadata, coordinates persistence |
| Data Access | Spring Data JPA, Hibernate | Spring Boot managed | Maps the Photo entity to Oracle and executes repository queries |
| Storage | Oracle Database Free/XE | Container image latest / XE-compatible JDBC URL | Stores photo metadata and image BLOB data |
| Delivery | Docker, Docker Compose | Dockerfile + compose | Runs the web app and Oracle database as containers |

### Data Storage & External Services

The application stores all photo metadata and binary image content in a single Oracle database table named `PHOTOS`. Beyond the database, the only notable external dependency at runtime is the Bootstrap CDN used by the server-rendered UI for styling and client-side bundle delivery.

### Key Architectural Decisions

- Uses a classic layered Spring MVC design where controllers delegate all business logic and persistence orchestration to a single `PhotoServiceImpl` service.
- Persists uploaded images as Oracle BLOB data instead of filesystem storage, which keeps the application stateless from a file-hosting perspective.
- Uses server-rendered Thymeleaf pages for navigation while enhancing uploads with client-side JavaScript for drag-and-drop and immediate gallery updates.

## Component Relationships

```mermaid
flowchart LR
subgraph Presentation["Presentation"]
IndexView["index.html"]
DetailView["detail.html"]
UploadClient["upload.js"]
HomeControllerNode["HomeController"]
DetailControllerNode["DetailController"]
PhotoFileControllerNode["PhotoFileController"]
end

subgraph Business["Business Logic"]
PhotoServiceNode["PhotoService"]
PhotoServiceImplNode["PhotoServiceImpl"]
UploadResultNode["UploadResult"]
end

subgraph DataAccess["Data Access"]
PhotoRepoNode["PhotoRepository"]
PhotoEntityNode["Photo Entity"]
end

subgraph Infra["Infrastructure"]
SpringBootNode["Spring Boot Runtime"]
TxNode["Transactional Boundary"]
OracleNode["Oracle Database"]
end

IndexView -->|"submits uploads to"| UploadClient
IndexView -->|"binds model data from"| HomeControllerNode
DetailView -->|"binds model data from"| DetailControllerNode
UploadClient -->|"calls"| HomeControllerNode
HomeControllerNode -->|"delegates"| PhotoServiceNode
DetailControllerNode -->|"delegates"| PhotoServiceNode
PhotoFileControllerNode -->|"delegates"| PhotoServiceNode
PhotoServiceNode -->|"implemented by"| PhotoServiceImplNode
PhotoServiceImplNode -->|"returns"| UploadResultNode
PhotoServiceImplNode -->|"queries and saves"| PhotoRepoNode
PhotoRepoNode -->|"maps"| PhotoEntityNode
PhotoRepoNode -->|"executes against"| OracleNode
SpringBootNode -.->|"creates and wires"| Presentation
TxNode -.->|"wraps service methods"| PhotoServiceImplNode
```

### Component Inventory

| Component | Layer | Type | Responsibility |
|---|---|---|---|
| `index.html` | Presentation | Thymeleaf template | Displays the gallery, upload area, and flash/error messages |
| `detail.html` | Presentation | Thymeleaf template | Shows a single photo, metadata, navigation, and delete action |
| `upload.js` | Presentation | Browser script | Validates dropped files, posts multipart uploads, and prepends new cards to the gallery |
| `HomeController` | Presentation | MVC controller | Handles gallery rendering and upload responses |
| `DetailController` | Presentation | MVC controller | Handles detail page rendering and delete operations |
| `PhotoFileController` | Presentation | MVC controller | Streams image bytes with cache-control headers |
| `PhotoServiceImpl` | Business Logic | Service | Applies upload rules, extracts image dimensions, and coordinates CRUD operations |
| `PhotoRepository` | Data Access | Spring Data repository | Executes Oracle-specific native SQL for ordered listing and navigation |
| `Photo` | Data Access | JPA entity | Represents persisted photo metadata and BLOB content |
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Assessment Overview

This directory contains supplementary assessment documents generated from the repository analysis. Use the links below to navigate to the detailed fact files that were copied into this versioned report.

- [architecture-diagram.md](architecture-diagram.md) — High-level application architecture and detailed component relationship diagrams.
- [dependency-map.md](dependency-map.md) — Declared build dependencies grouped by functional category, including test dependencies.
- [api-service-contracts.md](api-service-contracts.md) — Service catalog, endpoint inventory, communication patterns, and API sequence flow.
- [data-architecture.md](data-architecture.md) — Database configuration, entity model, repository methods, and data ownership boundaries.
- [configuration-inventory.md](configuration-inventory.md) — Configuration sources, runtime profiles, properties, secrets handling, and runtime settings.
- [business-workflows.md](business-workflows.md) — Core domain entities, user workflows, business rules, and workflow sequence diagram.
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# Core Business Workflows

The Photo Album application supports a simple user journey: upload image files, browse the gallery, inspect photo details, and remove photos when no longer needed. Its business logic is concentrated around validating upload eligibility, preserving metadata, and presenting stored photos in a user-friendly order.

## Domain Entities

| Entity | Service / Bounded Context | Description | Key Relationships |
|---|---|---|---|
| `Photo` | Photo Management | Core business record representing a user-uploaded image plus its display metadata | Serves as the source of truth for gallery cards, detail views, navigation, and deletion |
| `UploadResult` | Photo Management | Transient workflow object describing whether an individual file upload succeeded or failed | Produced during upload processing and converted into the JSON response payload |

## Service-to-Domain Mapping

| Service | Domain Context | Owned Entities | External Dependencies |
|---|---|---|---|
| `photoalbum-java-app` | Photo Management | `Photo`, `UploadResult` | Oracle database for persistence; browser clients for UI-driven workflows |
| `oracle-db` | Persistence Infrastructure | Physical storage for `Photo` records | None beyond its role as the backing data store |

## Primary Workflows

### Workflow 1: Upload Photos

A user drags photos into the gallery page or selects them through the file picker. The browser script performs a first pass of MIME type and file size validation, then posts the accepted files to `/upload`. The service layer validates each file again, rejects unsupported or empty uploads, extracts image dimensions when possible, assigns a UUID-based stored filename for compatibility, saves the photo bytes and metadata, and returns a per-file success or failure outcome.

Business rules involved:
- Only JPEG, PNG, GIF, and WebP files are accepted.
- Each file must be non-empty and no larger than 10 MB.
- Upload success is reported per file so mixed-result batches can still partially succeed.
- Image dimension extraction is best-effort; failure to read dimensions does not block persistence.

### Workflow 2: Browse Gallery and View Photo Details

When a user opens `/`, the application retrieves all photos ordered by most recent upload time and renders them as gallery cards. Selecting a card opens `/detail/{id}`, where the application loads the chosen photo, computes previous/next navigation targets based on upload timestamps, and displays metadata such as file size, MIME type, and image dimensions.

Business rules involved:
- Gallery ordering is newest-first.
- Missing photo identifiers gracefully redirect the user back to the gallery.
- Previous and next navigation is derived from upload time, not filename or insertion order.

### Workflow 3: Delete a Photo

From the detail page, a user can submit the delete action for a specific photo. The service checks whether the record exists, removes it from the database when present, and redirects the user back to the gallery with a success or error flash message.

Business rules involved:
- Deletion only succeeds when the target photo exists.
- The UI always returns the user to the gallery after the operation.
- User confirmation is required in the browser before the delete form is submitted.

## Cross-Service Data Flows

There is no multi-service business composition layer in this application. Business data flows from the browser to the Spring Boot application and then to Oracle, with the same service acting as the source of truth for validation, persistence, and presentation. When failures occur, the application degrades in business-visible ways: upload batches return per-file error messages, missing detail records redirect to the gallery, and delete attempts surface a user-facing error message instead of throwing a visible exception.

## Business Workflow Sequence

```mermaid
sequenceDiagram
participant User
participant Browser as "Gallery UI"
participant Home as "HomeController"
participant Service as "PhotoServiceImpl"
participant Repo as "PhotoRepository"
participant DB as "Oracle Database"

User->>Browser: Drop image files into upload zone
Browser->>Browser: Validate file type and size client-side
Browser->>Home: Submit accepted files to /upload
Home->>Service: Process each file
Service->>Service: Enforce upload rules and extract metadata
alt File is valid
Service->>Repo: Save Photo record
Repo->>DB: Persist metadata and image BLOB
DB-->>Repo: Stored photo
Repo-->>Service: Persisted entity
Service-->>Home: Success with photo id
Home-->>Browser: JSON response with uploaded photo summary
Browser-->>User: Show success and prepend new gallery card
else File is invalid or save fails
Service-->>Home: Failure result with error message
Home-->>Browser: JSON response with failedUploads entry
Browser-->>User: Show upload error message
end
```

## Business Rules & Decision Logic

- **Validation rules:** The application accepts only JPEG, PNG, GIF, and WebP uploads, enforces a 10 MB per-file limit, and rejects empty files.
- **Decision logic:** Upload processing follows a per-file success/failure model so one bad file does not block the entire batch.
- **Computed values:** The service derives image width and height from image bytes when available, and the UI computes human-readable file size displays and formatted upload timestamps.
- **State transitions:** A `Photo` record moves from not persisted to persisted on upload and from persisted to removed on delete; there are no intermediate approval states.
- **Transactions:** `PhotoServiceImpl` is annotated with `@Transactional`, so persistence operations run inside Spring-managed transaction boundaries.
- **Error handling and authorization:** The application logs operational failures and converts them into redirects or structured upload errors. No business-level authorization rules or role checks were detected.
Loading