Skip to content

Submission: Senior Full Stack Developer Case Study#87

Open
Deryew wants to merge 25 commits into
supplycart:masterfrom
Deryew:master
Open

Submission: Senior Full Stack Developer Case Study#87
Deryew wants to merge 25 commits into
supplycart:masterfrom
Deryew:master

Conversation

@Deryew
Copy link
Copy Markdown

@Deryew Deryew commented Apr 19, 2026

Summary

Full-stack e-commerce application built with Laravel 13, Vue 3 (Inertia.js), and TailwindCSS.

Core Requirements (All 7 completed)

  • Guest registration and login
  • Product listing with browse capability
  • Add to cart functionality
  • Place order from cart
  • Order history
  • Logout

Bonus Requirements (All 6 completed)

  • Email verification (with Mailpit for local testing)
  • Activity logging (login, logout, add to cart, place order)
  • Product filtering by brand, category, and search
  • User-specific pricing (VIP users see discounted prices)
  • 65 feature tests covering auth, products, cart, orders, and payments
  • Docker deployment (single command setup)

Additional Features

  • Stripe Checkout integration with webhook handling
  • Pessimistic locking to prevent duplicate orders
  • Price snapshots at checkout time
  • Stock validation and management
  • Cart count caching for performance
  • Responsive design

Setup

# Docker (recommended)
docker compose up --build -d
docker compose exec app php artisan db:seed --force
# Visit http://localhost:8080

Deryew and others added 25 commits April 19, 2026 23:22
…rvices, requests, resources, and event logging
Laravel 11 base Controller no longer includes AuthorizesRequests by
default, causing 'authorize()' calls in CartController and
OrderController to fail.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
JsonResource::collection() wraps items in a 'data' key which breaks
Vue component prop access. Inline item mapping in CartResource and
OrderResource to produce flat arrays. Controllers now use
resolve() to strip the outer wrapper for Inertia responses.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace activeCart relationship chain with a single aggregated query
to count cart items. Previously caused 2+ queries on every request.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add indexes on products(brand_id), products(category_id),
cart_items(product_id), and user_prices(product_id) to support
filtering and join queries efficiently.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
CartService now checks product is active and has sufficient stock
before adding to cart. Form requests enforce max quantity of 99
with custom error messages.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Laravel paginator with through() exposes links at top level,
not under meta.links like resource collections.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
55 tests covering core flows:
- Products: listing, filtering by brand/category/search, inactive
  products hidden, user-specific pricing
- Cart: add/update/remove items, clear cart, authorization,
  validation (product exists, quantity bounds)
- Orders: place order, order number generation, stock decrement,
  cart deactivation, price snapshot, user-specific pricing,
  order history, detail view, authorization

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Products page is now the default landing page, accessible without
authentication. Guests see login/register in the nav bar. Clicking
"Add to Cart" redirects guests to the login page. Cart and orders
still require authentication.

- Add AppLayout with guest/auth-aware navigation
- ProductService accepts nullable user for guest browsing
- Root route redirects to /products

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Fix type coercion for brand/category filter values and add
preserveScroll for smoother filter experience. Update tests
to reflect publicly accessible products page.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Order status field remains in DB/API for future fulfillment flow integration.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add login credentials, core flow walkthrough, and user-specific pricing
explanation to README. Restructure SETUP.md with Docker (recommended) and
local development options.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Route documentation with request/response shapes and validation rules.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Multi-stage Dockerfile with Nginx + PHP-FPM + Supervisor. Single container
setup using SQLite with volume persistence. Run with docker compose up.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Laravel 13 auto-discovers listeners from the Listeners/ directory.
The custom EventServiceProvider was also registering them manually,
causing every event (activity logs, verification emails) to fire twice.
Removed EventServiceProvider from providers and rely on auto-discovery.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Cache the cart count with a 60-second TTL instead of querying on every
request. Invalidate on add, update, remove, clear, and order placement.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add Mailpit service to Docker Compose for capturing outgoing emails.
Update .env.example to use SMTP on port 1025 by default.
Inbox available at http://localhost:8025.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add product listing, cart, checkout, order history, and Mailpit
screenshots. Document how to verify activity logs via tinker.
Add Mailpit setup instructions for both Docker and local development.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Document how to use Stripe CLI to forward webhook events to localhost
for both Docker and local development setups.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant