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,70 @@
# API & Service Communication Contracts

The application exposes a compact HTTP surface with browser-facing endpoints for gallery browsing, upload, detail navigation, image retrieval, and deletion. Communication is synchronous within a single deployable service.

## Service Catalog

| Service | Port | Category | Purpose |
|---|---:|---|---|
| photo-album (single Spring Boot module) | 8080 | Business | Serves UI pages, upload API, and image delivery endpoints |

## API Endpoints Inventory

| Service | Method | Path | Request Type | Response Type |
|---|---|---|---|---|
| photo-album (`HomeController`) | GET | `/` | No body | HTML view (`index`) |
| photo-album (`HomeController`) | POST | `/upload` | Multipart `files[]` | JSON map with `success`, `uploadedPhotos`, `failedUploads` |
| photo-album (`DetailController`) | GET | `/detail/{id}` | Path param `id` | HTML view (`detail`) or redirect |
| photo-album (`DetailController`) | POST | `/detail/{id}/delete` | Path param `id` | Redirect to `/` with flash message |
| photo-album (`PhotoFileController`) | GET | `/photo/{id}` | Path param `id` | Binary resource with media type headers or 404/500 |

## Management & Observability Endpoints

| Service | Endpoint | Custom Metrics (if any) |
|---|---|---|
| photo-album | None explicitly declared in code/config | None detected |

## DTOs & Contracts

API contract objects include:
- `UploadResult` (mutable POJO): service-level upload outcome object used to represent success/failure and associated photo id.
- `Photo` (domain entity reused in API/view model): used for response data in controllers and template rendering.
- Upload response payload is composed as a dynamic `Map<String,Object>` with uploaded/failed item lists.

No OpenAPI/Swagger, GraphQL schema, or protobuf contract files were detected. Serialization relies on Spring Boot JSON/Jackson defaults.

## Communication Patterns

All service communication is synchronous request/response over HTTP between browser clients and the single backend service. Controllers delegate to `PhotoServiceImpl`, which performs transactional database work through `PhotoRepository`. No async messaging, circuit breaker, retry policy, or service discovery framework is present. API availability depends on datasource readiness; if Oracle is unavailable, persistence-backed operations fail. Security posture: no explicit authentication, authorization, or TLS enforcement is configured in application code.

## Service Technology Matrix

| Service | Web | Data Access | Discovery | Gateway | Actuator | Cache | Metrics |
|---|---|---|---|---|---|---|---|
| photo-album | Spring MVC + Thymeleaf | Spring Data JPA / Hibernate / Oracle JDBC | None | None | None detected | None detected | None detected |

## Service Communication Sequence

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

User->>Home: POST /upload (multipart files)
Home->>Service: uploadPhoto(file)
Service->>Service: validate mime type and size
alt Validation passes
Service->>Repo: save(Photo)
Repo->>DB: INSERT photo metadata and BLOB
DB-->>Repo: persisted row
Repo-->>Service: saved Photo(id)
Service-->>Home: UploadResult success
Home-->>User: 200 JSON upload summary
else Validation fails
Service-->>Home: UploadResult failure
Home-->>User: 200 JSON with failedUploads
end
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
# Architecture Diagram

This application is a single Spring Boot web service that serves Thymeleaf pages and REST-style upload/file endpoints for photo management backed by an Oracle database.

## Application Architecture

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

subgraph App["Application Layer - Spring Boot 2.7"]
MVC["Spring MVC Controllers"]
Views["Thymeleaf Templates"]
Service["PhotoService"]
end

subgraph Data["Data Layer"]
Repo["Spring Data JPA Repository"]
Oracle[("Oracle Database PHOTOS table")]
Blob[("BLOB photo data")]
end

Browser -->|"GET/POST requests"| MVC
MVC -->|"render views"| Views
MVC -->|"invoke business logic"| Service
Service -->|"CRUD and queries"| Repo
Repo -->|"SQL operations"| Oracle
Oracle -->|"stores image bytes"| Blob
```

### Technology Stack Summary

| Layer | Technology | Version | Purpose |
|---|---|---|---|
| Presentation | Spring MVC + Thymeleaf | Spring Boot 2.7.18 | Handles gallery UI and request routing |
| Business | Spring Service + Validation | Spring Boot 2.7.18 | Enforces upload rules and photo lifecycle operations |
| Data Access | Spring Data JPA + Hibernate | Spring Boot 2.7.18 | Repository abstraction and ORM integration |
| Data Store | Oracle JDBC (`ojdbc8`) | Runtime dependency | Persistent storage for metadata and BLOB image data |

### Data Storage & External Services

The primary runtime datastore is Oracle, with the `PHOTOS` table storing both metadata and raw image data in a BLOB column. Test executions use H2 in-memory storage via the test profile, and there are no outbound third-party API integrations in core request flows.

### Key Architectural Decisions

- Stores photo binary content directly in the database (`@Lob`) instead of serving from external object storage.
- Uses constructor injection and a thin-controller/service/repository layering to keep controller logic focused on HTTP concerns.
- Uses environment/profile-based datasource switching (`default`/`docker` runtime vs `test` profile with H2).

## Component Relationships

```mermaid
flowchart LR
subgraph Presentation["Presentation"]
HomeCtrl["HomeController"]
DetailCtrl["DetailController"]
FileCtrl["PhotoFileController"]
end

subgraph Business["Business Logic"]
PhotoSvc["PhotoServiceImpl"]
UploadRes["UploadResult"]
end

subgraph DataAccess["Data Access"]
PhotoRepo["PhotoRepository"]
PhotoEntity["Photo Entity"]
end

subgraph Infra["Infrastructure"]
Tx["Spring Transactions"]
Log["SLF4J Logging"]
OracleDB["Oracle DB"]
end

HomeCtrl -->|"list/upload"| PhotoSvc
DetailCtrl -->|"detail/delete/navigation"| PhotoSvc
FileCtrl -->|"fetch bytes"| PhotoSvc
PhotoSvc -->|"save/query/delete"| PhotoRepo
PhotoRepo -->|"maps rows"| PhotoEntity
PhotoRepo -->|"native SQL"| OracleDB
Tx -.->|"transaction boundary"| PhotoSvc
Log -.->|"cross-cutting logs"| HomeCtrl
Log -.->|"cross-cutting logs"| DetailCtrl
Log -.->|"cross-cutting logs"| FileCtrl
```

### Component Inventory

| Component | Layer | Type | Responsibility |
|---|---|---|---|
| HomeController | Presentation | MVC Controller | Renders gallery and handles batch upload requests |
| DetailController | Presentation | MVC Controller | Renders single photo detail and delete actions |
| PhotoFileController | Presentation | MVC Controller | Streams image binary content for `/photo/{id}` |
| PhotoServiceImpl | Business Logic | Service | Validates files, handles photo persistence and navigation operations |
| UploadResult | Business Logic | DTO | Captures per-file upload outcome for API responses |
| PhotoRepository | Data Access | Spring Data Repository | Executes CRUD and custom Oracle-native queries |
| Photo | Data Access | JPA Entity | Represents persisted photo metadata and image BLOB |
| Spring Transactions | Infrastructure | Framework Concern | Ensures atomic writes and consistent data operations |
| SLF4J Logging | Infrastructure | Cross-cutting Concern | Provides operational/error tracing across controllers and service |
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Assessment Overview

This directory contains supplementary architecture and analysis documents generated during application assessment.

- [architecture-diagram.md](./architecture-diagram.md) — High-level and component-level architecture diagrams.
- [dependency-map.md](./dependency-map.md) — External dependency inventory and compatibility observations.
- [api-service-contracts.md](./api-service-contracts.md) — Service catalog, endpoint contracts, and communication sequence.
- [data-architecture.md](./data-architecture.md) — Persistence model, repository methods, and data classification notes.
- [configuration-inventory.md](./configuration-inventory.md) — Configuration sources, profiles, properties, and secrets workflow.
- [business-workflows.md](./business-workflows.md) — Core business processes and decision logic.
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# Core Business Workflows

The application enables users to upload, browse, inspect, and delete photos in a lightweight gallery experience. Core workflows focus on validating uploads and managing a photo collection lifecycle.

## Domain Entities

| Entity | Service / Bounded Context | Description | Key Relationships |
|---|---|---|---|
| Photo | Photo Management | Canonical record for stored image content and metadata | Used by upload, gallery listing, detail viewing, and deletion workflows |
| UploadResult | Photo Management | Operation result object for per-file upload outcomes | Produced by upload workflow and aggregated into response payload |

## Service-to-Domain Mapping

| Service | Domain Context | Owned Entities | External Dependencies |
|---|---|---|---|
| photo-album | Photo Management | `Photo`, `UploadResult` | Oracle database via repository layer |

## Primary Workflows

### Workflow 1: Upload Photos to Gallery

Entry point: `POST /upload`
1. User selects one or more files and submits upload.
2. Service validates MIME type, file size, and non-empty content.
3. Service extracts image dimensions and prepares persisted `Photo` entity.
4. Repository saves metadata and binary content.
5. Response aggregates successful and failed files for user feedback.

### Workflow 2: Browse, View Detail, and Delete

Entry points: `GET /`, `GET /detail/{id}`, `POST /detail/{id}/delete`, `GET /photo/{id}`
1. Gallery page requests photo list sorted by newest uploads.
2. Detail page resolves specific photo plus previous/next navigation candidates.
3. Binary endpoint streams image bytes for rendering.
4. Delete action removes selected photo and returns to gallery with status message.

## Cross-Service Data Flows

No cross-service composition is present. All workflow data is owned and served by a single service and one backing datastore, so business responses are assembled internally without downstream service joins or fallback routing.

## Business Workflow Sequence

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

User->>UI: Submit photo upload request
UI->>Service: Process uploaded files
Service->>Service: Validate file type and size rules
alt File valid
Service->>Repo: Save photo record
Repo->>DB: Persist metadata and image content
DB-->>Repo: Save successful
Repo-->>Service: Persisted photo id
else File invalid
Service-->>Service: Mark upload as failed
end
Service-->>UI: Return upload summary
UI-->>User: Show success/failure results in gallery
```

## Business Rules & Decision Logic

- Uploads must be image MIME types from an allowed list and within configured maximum size.
- Empty files are rejected before persistence.
- Navigation logic selects previous/next photos based on upload timestamp ordering.
- Deletion only succeeds when the target photo exists; otherwise user receives not-found feedback.
- Transaction boundary is at service layer (`@Transactional`) to keep write operations consistent.
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# Configuration & Externalized Settings Inventory

Configuration is primarily file-based with Spring properties for server, datasource, JPA, upload limits, and logging. Runtime behavior switches mainly through Spring profiles (`default`, `docker`, and `test`) and container environment overrides.

## Configuration Sources

| Source | Type | Path/Location | Notes |
|---|---|---|---|
| Main Spring properties | Application config | `src/main/resources/application.properties` | Base server, datasource, JPA, upload, logging settings |
| Docker profile properties | Application config | `src/main/resources/application-docker.properties` | Overrides for containerized runtime profile |
| Test profile properties | Test config | `src/test/resources/application-test.properties` | H2 in-memory datasource for tests |
| Docker Compose service env | Container runtime config | `docker-compose.yml` | Injects active profile and datasource credentials |
| Docker image runtime options | Container startup config | `Dockerfile` | Defines `JAVA_OPTS` and jar startup command |
| Azure setup env output | Provisioning config artifact | `.env` (generated by `azure-setup.ps1`) | Script writes resource and DB environment values |

## Build Profiles

| Profile | Activation | Purpose | Key Dependencies/Plugins |
|---|---|---|---|
| Maven default build | Standard `mvn` lifecycle | Build/packaging Spring Boot application jar | `spring-boot-maven-plugin` |

## Runtime Profiles

| Profile | Activation Method | Config Files | Key Overrides |
|---|---|---|---|
| default | No explicit profile variable | `application.properties` | Oracle datasource, debug-level app logging |
| docker | `SPRING_PROFILES_ACTIVE=docker` | `application.properties` + `application-docker.properties` | Docker-specific Oracle URL and adjusted logging levels |
| test | `@ActiveProfiles("test")` in tests | `application-test.properties` | H2 datasource and non-SQL logging for tests |

## Properties Inventory

| Property Key | Default | Profiles | Source |
|---|---|---|---|
| `server.port` | `8080` | default, docker | application properties files |
| `spring.datasource.url` | Oracle JDBC URL | default, docker, test override | application / docker / test properties |
| `spring.datasource.username` | `photoalbum` (runtime), `sa` (test) | default, docker, test | application / docker / test properties |
| `spring.datasource.password` | configured (runtime), blank (test) | default, docker, test | application / docker / test properties |
| `spring.jpa.hibernate.ddl-auto` | `create` (`create-drop` in test) | default, docker, test | application / docker / test properties |
| `spring.servlet.multipart.max-file-size` | `10MB` | default, docker | application properties files |
| `spring.servlet.multipart.max-request-size` | `50MB` | default, docker | application properties files |
| `app.file-upload.max-file-size-bytes` | `10485760` | default, docker, test | application / docker / test properties |
| `app.file-upload.allowed-mime-types` | jpeg/png/gif/webp list | default, docker, test | application / docker / test properties |
| `logging.level.com.photoalbum` | DEBUG/INFO by profile | default, docker, test | application / docker / test properties |

## Startup Parameters & Resource Requirements

| Service | JVM/Runtime Options | Memory | Instance Count |
|---|---|---|---|
| photo-album container | `java $JAVA_OPTS -jar app.jar` | `JAVA_OPTS="-Xmx512m -Xms256m"` in Dockerfile | 1 instance in docker-compose |
| oracle-db container | Oracle image defaults | Not explicitly constrained in compose | 1 instance in docker-compose |

## Startup Dependency Chain

1. `oracle-db` starts first and must pass container health check.
2. `photoalbum-java-app` starts after `oracle-db` is healthy (`depends_on` with `condition: service_healthy`).
3. Application handles requests after datasource initialization succeeds.

## Secrets & Sensitive Configuration

| Secret Reference | Type | Storage (masked) |
|---|---|---|
| `spring.datasource.password` | Database credential | Application property / environment variable (`[MASKED]`) |
| `ORACLE_PASSWORD`, `APP_USER_PASSWORD` | Container DB credential | `docker-compose.yml` environment (`[MASKED]`) |
| `POSTGRES_PASSWORD` (script-generated) | Provisioning credential | `.env` output from setup script (`[MASKED]`) |

### Secrets Provisioning Workflow

Secrets are provided through local configuration files and environment variables. In local/container flows, docker-compose injects DB credentials directly to Oracle and the app service; in scripted Azure setup, credentials are generated/set and written to `.env` for subsequent use by tooling and deployment steps. No managed identity or external secret manager integration is declared in this repository.

## Feature Flags

| Flag Name | Default | Controlled By |
|---|---|---|
| None detected | N/A | N/A |

## Framework & Runtime Versions

| Component | Version | Source |
|---|---|---|
| Spring Boot | 2.7.18 | `pom.xml` parent |
| Java target | 8 | `pom.xml` properties and Docker base image |
| Maven (build image) | 3.9.6 | `Dockerfile` build stage |
| Oracle JDBC driver | `ojdbc8` | `pom.xml` dependency |
| Container JRE | Eclipse Temurin 8 JRE | `Dockerfile` runtime stage |
| Oracle container DB | `gvenzl/oracle-free:latest` | `docker-compose.yml` |
Loading