This is a submission for the GitHub Finish-Up-A-Thon Challenge
## My Project
StorePro is a comprehensive web application for inventory and product management. It enables users to seamlessly manage their own product catalogs: adding items with images, tracking stock levels, filtering and searching through products, and visualizing key financial metrics (estimated expenses, estimated revenue, total stock) via an interactive dashboard with dynamic charts.
This project was born out of a concrete, real-world need: providing small businesses with a simple yet professional management tool. What originally started as a personal learning exercise to master Go and React has become, through this challenge, an application I am deeply proud to showcase.
The project is structured as a monorepo consisting of:
- A Go Backend: REST API, PostgreSQL, JWT authentication with token rotation, Cloudinary for image management, and Resend for transactional emails.
- A React Frontend: Built with Vite, TanStack React Query, Tailwind CSS + DaisyUI, and Recharts.
Demo
- GitHub Repository: https://github.com/babader08/app-gestion-stock
- Backend (Hugging Face Spaces): https://babamboup697-app-gestion-stock.hf.space
- Frontend (Vercel): https://app-gestion-stock-opal.vercel.app
The live dashboard displays real-time statistics, a product list equipped with infinite scroll, and revenue/expense charts.
The Comeback Story
When I picked this project back up for the challenge, the core features were functional, but several serious underlying issues needed to be addressed before it could be considered a truly professional-grade application.
How I Cleaned It Up / Polished It
Here is everything I fixed, hardened, and added during this hackathon:
1. Fixing Real Bugs in HTTP Handlers
While reviewing the codebase, I identified and resolved 4 critical bugs:
- Missing return statement after a Cloudinary upload error: This could have led to a nil-pointer panic runtime crash.
-
Incorrect HTTP Status Code: The API was returning a
401 Unauthorizedstatus code for invalid incoming JSON payloads instead of a proper400 Bad Request. -
Unsafe Type Assertion: A type assertion without an
okcheck inside a handler was fixed to eliminate potential production crashes. -
Dead Code Removal: Fixed a redundant
productvariable allocation that was immediately overwritten.
2. Securing the Upload Route
The /api/upload route was previously public, meaning anyone could upload arbitrary files to my Cloudinary account without authentication. I successfully moved this endpoint behind the secure requireAuth middleware layer.
3. Replacing Fragile Error Comparisons
One of my handlers was comparing database errors using a brittle string check (err.Error() == "..."), which would break upon any slight message change. I refactored this by introducing a sentinel error repository.ErrProductNotFound and switching to Go's robust errors.Is mechanism.
4. Writing 48 Unit Tests Across Two Layers
I designed and executed a comprehensive testing suite with zero external dependencies and no live database connections:
- 34 tests covering the service layer business logic (auth + products).
-
14 tests covering the handler layer (performing real HTTP requests testing using the native
httptestpackage).
go
func TestRefreshAccessToken_InvalidToken(t *testing.T) {
repo := &mockAuthRepo{
getUserIDByTokenFn: func(tokenHash []byte, scope string) (int, error) {
return 0, errors.New("token invalide")
},
}
svc := newTestAuthService(repo, &mockMailer{})
_, _, err := svc.RefreshAccessToken(context.Background(), "bad-token")
if !errors.Is(err, ErrInvalidToken) {
t.Errorf("expected ErrInvalidToken, got %v", err)
}
}
Top comments (0)