Wild Beyond is a full-stack Spring Boot application that combines wildlife-focused content discovery with a role-based e-commerce workflow. The platform supports public users plus authenticated BUYER, SELLER, and ADMIN roles.
It delivers:
- Public content experience (Home, Blog, Explore, Wildlife Photography).
- Product marketplace (create/list/view/update/delete).
- Shopping flow (cart, checkout, orders).
- Role-based dashboards and administration.
- Home page
- Latest stories section
- Visual story blocks
- Explore page
- Travel stories section
- Sign in page
- Product add page
- Seller dashboard
- Orders view page
- Home page with dynamic featured stories and products.
- Blog page with internal content + external feed enrichment.
- Explore module by categories (animals, birds, ecosystems).
- Explore detail pages with dynamic image/content handling.
- Wildlife photography gallery view.
- About page.
- Public product browsing and details.
- Product photo serving endpoint.
- Seller product creation with optional image upload.
- Seller/Admin product edit and delete.
- Validation and error feedback through flash messages.
- Add item to cart with quantity checks.
- Remove item from cart.
- Checkout from cart.
- Stock validation during checkout.
- Redirect to orders on successful checkout.
- Error handling for empty cart and insufficient stock.
- Buyer order history and order details.
- Seller selling-order visibility.
- Admin full order visibility.
- Role-based dashboard routing:
- Admin dashboard
- Seller dashboard
- Buyer dashboard
- Spring Security filter-chain based access control.
- Role-based route restrictions (BUYER/SELLER/ADMIN).
- Form login with email as principal.
- HTTP Basic support for API clients.
- CSRF protection (API route exclusions for client usability).
- Register with role selection (BUYER/SELLER).
- Login/logout flows.
- BCrypt password hashing.
- Email-based user loading.
- URL-level + method-level authorization.
- Create product.
- View all products.
- View single product details.
- Update product.
- Delete product.
- Seller ownership check + admin override.
- Product image handling.
- Session-based cart storage.
- Add/remove cart lines.
- Checkout conversion from cart to order.
- Per-item stock check.
- Stock reduction on successful checkout.
- Cart clear on success.
- Place order through API/MVC flow.
- Buyer own-order retrieval.
- Seller product-order retrieval.
- Admin all-orders retrieval.
- Order detail retrieval.
- Order deletion (admin restricted in REST).
- Internal blog post listing/detail.
- External blog feed merge.
- Explore content by category + slug.
- Wildlife gallery generation.
- External media resolution with fallbacks.
- Admin user listing view.
- Role-based dashboard metrics.
- Startup role and admin seeding.
- Java 17
- Spring Boot 4
- Spring Security
- Spring Data JPA (Hibernate)
- Spring Validation
- Spring Web MVC
- PostgreSQL driver
- Lombok
- Thymeleaf templates
- HTML/CSS with utility-class based styling
- Template fragments for reusable UI sections
- Guardian API
- NewsAPI
- Wikipedia Summary API
src/main/java/com/wildbeyond
config/ -> security + app bootstrapping configuration
controller/ -> MVC presentation layer
controller/rest/ -> REST presentation layer
service/ -> business logic layer
repository/ -> persistence abstraction layer
model/ -> domain entities
dto/ -> request/response/view data contracts
exception/ -> centralized error handling
src/main/resources
templates/ -> Thymeleaf views
static/ -> static assets
application.yml -> environment-driven runtime config
src/test/java/com/wildbeyond
controller/ -> controller tests
service/ -> service tests
exception/ -> exception handler tests
repository/ -> repository tests
- GET /auth/login
- GET /auth/register
- POST /auth/register
- POST /auth/logout (handled by Spring Security)
- GET /
- GET /home
- GET /index
- GET /blog
- GET /blog/{id}
- GET /explore
- GET /explore/{category}/{slug}
- GET /explore/wildlife-photography
- GET /about
- GET /products
- GET /products/{id}
- GET /products/{id}/photo
- GET /products/new
- GET /products/edit/{id}
- POST /products
- POST /products/edit/{id}
- GET /products/delete/{id}
- POST /products/{id}/delete
- POST /products/{id}/edit
- GET /buyer/cart
- GET /seller/cart
- POST /buyer/cart/add/{productId}
- POST /seller/cart/add/{productId}
- POST /buyer/cart/remove/{productId}
- POST /seller/cart/remove/{productId}
- POST /buyer/cart/checkout
- POST /seller/cart/checkout
Compatibility redirects:
- /cart/** -> canonical role-scoped cart route
- GET /buyer/orders
- GET /seller/orders
- GET /admin/orders
- GET /buyer/orders/{id}
- GET /seller/orders/{id}
- GET /admin/orders/{id}
- POST /buyer/orders
- POST /seller/orders
- POST /admin/orders
Compatibility redirects:
- /orders/** -> canonical role-scoped orders route
- GET /dashboard
- GET /admin
- GET /seller/dashboard
- GET /buyer/dashboard
- GET /admin/users
- GET /admin/users/{id}
- POST /admin/users/{id}/edit
- POST /admin/users/{id}/delete
Compatibility redirects:
- /users/** -> /admin/users/**
- GET /api/products
- GET /api/products/{id}
- POST /api/products
- PUT /api/products/{id}
- DELETE /api/products/{id}
- POST /api/orders
- GET /api/orders/my
- GET /api/orders/{id}
- GET /api/orders
- DELETE /api/orders/{id}
- Product write API: SELLER for create, SELLER/ADMIN for update/delete.
- Order create API: BUYER + SELLER (seller cannot order own products).
- Order admin list/delete APIs: ADMIN.
Prerequisites:
- Java 17
- PostgreSQL instance
Run:
./mvnw.cmd spring-boot:runApp URL:
- Create env file from template:
cp .env.example .env- Start application + database:
docker compose up --build- Access:
- App: http://localhost:8180
- DB: localhost:5432
Stop:
docker compose downReset with volume removal:
docker compose down -v- Create Render web service from repository (Docker deployment).
- Attach PostgreSQL service.
- Configure environment variables:
- DB_HOST
- DB_PORT
- DB_NAME
- DB_USERNAME
- DB_PASSWORD
- GUARDIAN_API_KEY (optional)
- NEWSAPI_KEY (optional)
- Create deploy hook in Render.
- Add GitHub secret RENDER_DEPLOY_HOOK.
- Push to main branch for deployment trigger.
Workflow file: .github/workflows/ci.yml
- Push: main, dev, feature/**
- Pull request: main, dev
- Checkout source
- Setup Java 17 (Temurin)
- Build (
./mvnw.cmd clean install -DskipTests) - Test (
./mvnw.cmd test) - Docker image build
- Upload surefire reports on failure
Deploy job runs only when:
- Event is push
- Branch is main
- Build job is successful
Deployment method:
- POST request to Render deploy hook from GitHub Action.
Primary tables and purpose:
- Stores account identity, credentials, status, and audit timestamps.
- Stores role names (ADMIN, SELLER, BUYER).
- Join table between users and roles (many-to-many mapping).
- Product catalog with seller owner, pricing, stock, description, and optional image blob/content type.
- Parent order records with buyer, status, order date, and total price.
- Child order lines linking order to products with quantity and unit price snapshot.
- Internal editorial content with publish flag and created timestamp.
This project includes controller, service, repository, exception, and context tests.
- src/test/java/com/wildbeyond/WildBeyondApplicationTests.java
- src/test/java/com/wildbeyond/controller/HomeControllerTest.java
- src/test/java/com/wildbeyond/controller/ProductControllerTest.java
- src/test/java/com/wildbeyond/controller/ProductRestControllerTest.java
- src/test/java/com/wildbeyond/controller/OrderControllerTest.java
- src/test/java/com/wildbeyond/controller/OrderRestControllerTest.java
- src/test/java/com/wildbeyond/controller/DashboardControllerTest.java
- src/test/java/com/wildbeyond/service/UserServiceTest.java
- src/test/java/com/wildbeyond/service/ProductServiceTest.java
- src/test/java/com/wildbeyond/service/OrderServiceTest.java
- src/test/java/com/wildbeyond/service/HomepageServiceTest.java
- src/test/java/com/wildbeyond/repository/HomepageRepositoryTest.java
- src/test/java/com/wildbeyond/exception/GlobalExceptionHandlerTest.java
- src/test/java/com/wildbeyond/exception/GlobalExceptionHandlerMvcTest.java
./mvnw.cmd testIn CI, tests are executed automatically in GitHub Actions before deployment.
- main: production-ready branch with deployment enabled.
- dev: integration branch.
- feature/**: isolated feature development.
- Push to main, dev, feature/**
- Pull requests targeting main and dev
- Checkout repository.
- Setup Java 17 + Maven cache.
- Build project.
- Run test suite.
- Build Docker image.
Deploy runs only when:
- Event is push.
- Branch is main.
- Build job passes.
- Deployment is triggered by Render deploy hook.
- Required GitHub secret: RENDER_DEPLOY_HOOK.
- Deploy hook is not hardcoded in repository files.
- Push to feature branch: CI runs, deploy does not run.
- PR to dev/main: CI runs, deploy does not run.
- Merge to main: CI runs, then deploy runs.
- Verify new revision in Render dashboard.
- HTTP Basic Auth for protected endpoints.
- Public endpoint: GET /api/products (no auth required).
- BUYER: buyer@test.com / seller123
- SELLER: seller@test.com / seller123
- ADMIN: admin@test.com / seller123
- Application is running.
- Database is running.
- At least one product exists before starting order tests.
-
TEST-1
- Method/URL: GET /api/products
- Auth: None
- Expected: 200
-
TEST-2
- Method/URL: GET /api/products
- Auth: None
- Expected: 200
-
TEST-3
- Method/URL: POST /api/products
- Auth: SELLER
- Expected: 201
-
TEST-4
- Method/URL: GET /api/products/{id}
- Auth: None
- Expected: 200
-
TEST-5
- Method/URL: PUT /api/products/{id}
- Auth: SELLER
- Expected: 200
-
TEST-6
- Method/URL: DELETE /api/products/{id}
- Auth: ADMIN
- Expected: 204
-
TEST-7
- Method/URL: POST /api/orders
- Auth: BUYER
- Expected: 201
-
TEST-8
- Method/URL: GET /api/orders/my
- Auth: BUYER
- Expected: 200
-
TEST-9
- Method/URL: GET /api/orders/{id}
- Auth: Authenticated user
- Expected: 200
-
TEST-10
- Method/URL: GET /api/orders
- Auth: ADMIN
- Expected: 200
-
TEST-11
- Method/URL: DELETE /api/orders/{id}
- Auth: ADMIN
- Expected: 204
- TEST-2 -> 200
- TEST-2 -> 200
- TEST-3 -> 201
- TEST-2 -> 200 (contains created product)
- TEST-4 -> 200
- TEST-5 -> 200
- TEST-6 -> 204
- TEST-4 -> 404 (deleted item)
- Re-run TEST-3 to create a product dependency
- TEST-7 -> 201
- TEST-8 -> 200
- TEST-9 -> 200
- TEST-10 -> 200
- TEST-11 -> 204
- TEST-9 -> 404 (deleted order)
- Browse products: public + all roles
- Create product: SELLER
- Update/delete product: SELLER/ADMIN
- Place order: BUYER + SELLER (seller own-product purchase blocked)
- View own orders: authenticated users
- View all orders: ADMIN
- Delete order: ADMIN
- POST /api/products without auth -> 401
- POST /api/products wrong credentials -> 401
- POST /api/products with BUYER role -> 403
- POST /api/orders with SELLER role (other seller product) -> 201
- POST /api/orders with SELLER role (own product) -> 403
- POST /api/orders without auth -> 401
- GET /api/orders with BUYER/SELLER role -> 403
- GET /api/products without auth -> 200
- GET /api/orders/my without auth -> 401
- Missing product/order id -> 404 with structured error response

















