
Smart Cycle
Smart Cycle is a modern, responsive frontend for an intelligent waste management and recycling system. Built with React and Vite, it provides intuitive interfaces for Residents, Drivers, Personnel, and Admins to manage schedules, donations, and recycling operations efficiently.
Table of Contents
Smart Cycle: Engineering a Role-Based Full-Stack Waste Management Platform
Introduction: Why This Project Is Harder Than It Looks
On the surface, a waste management platform might sound like a simple booking-and-tracking app. In reality, it is one of the more demanding categories of software to design well, because it isn't built around a single type of user performing a single type of action. It's built around four different actors, residents, drivers, recycling center operators, and administrators, who all touch the same underlying data, but need entirely different tools, permissions, and views to do their jobs.
This is the core problem Smart Cycle was built to solve: how do you design one coherent system that serves four very different workflows without turning into either four disconnected apps or one tangled mess of conditional logic?
The answer combines a React-based, role-driven frontend with a Spring Boot backend that owns all business rules, security enforcement, and workflow orchestration. Rather than treating the frontend and backend as loosely related pieces that happen to talk over HTTP, Smart Cycle treats them as two halves of a single operational system, each with clearly defined responsibilities, but tightly coordinated through a strict API contract.
Why Role-Based Architecture Is a Core Design Decision
Most systems that need to serve multiple types of users take one of two paths: build separate applications per user type, or build one application riddled with if (user.role === 'admin') checks scattered across the codebase. Both approaches tend to rot over time, separate apps duplicate effort and drift apart, while heavily branched UI logic becomes a maintenance nightmare as the number of roles grows.
Smart Cycle instead adopts role-aware routing, permissions, and workflows inside a single, unified system.
The four supported roles are:
All four roles authenticate against the same backend and consume the same underlying services, but each is routed to a dashboard and set of capabilities tailored specifically to their responsibilities. Shared concerns like authentication, notifications, and profile management are implemented exactly once, while dashboards render conditionally based on the authenticated user's identity and permissions.
The payoff of this design is consistency. A bug fix in the authentication flow benefits every role simultaneously. A new notification type doesn't need to be re-implemented four times. And because everything runs through the same codebase, there's a single source of truth for how the system behaves.
Frontend: A Unified React Application with Role-Aware Routing
The frontend is a single React application, not four separate ones. This is made possible by structuring routing around role-based route resolution rather than duplicating pages or apps per user type.
In practice, this means:
Key Frontend Technologies
API Communication Layer
Rather than scattering fetch or axios calls throughout individual components, Smart Cycle centralizes all API communication through Axios, configured with interceptors. This centralization handles three concerns consistently across the entire application:
1. Attaching authentication tokens to outgoing requests automatically, so individual components never need to manually manage auth headers
2. Handling unauthorized responses globally, if a request comes back with a 401, the interceptor can redirect to login or refresh the session in one place, rather than requiring every component to handle this case independently
3. Standardizing error handling, API errors are caught and formatted consistently, so error messages shown to the user (via React Toastify) follow a predictable pattern
This keeps networking logic out of UI components entirely. Components focus purely on rendering and user interaction; the Axios layer handles everything related to talking to the server.
Backend: Spring Boot as the Domain Authority
If the frontend is responsible for usability, the backend is responsible for correctness. This is a deliberate split: the frontend controls what users can see, but the backend controls what users can do. No business rule is ever trusted to the client, everything that matters is re-validated and enforced server-side.
The backend follows a classic layered architecture:
Controllers → Services → Repositories → DatabaseResponsibilities by Layer
This layering matters because it decouples business logic from both the UI and the persistence mechanism. If the database technology changed, or the frontend framework changed, the service layer, which encodes the actual rules of how waste management operations work, would remain untouched.
Designing Around Real-World Workflows, Not CRUD
A generic backend for this kind of system might expose endpoints like createCollectionRequest, updateRequest, and deleteRequest. Smart Cycle deliberately avoids this pattern.
Instead, the API surface is designed around the real-world actions that actually happen in a waste management operation:
This distinction matters more than it might initially seem. A generic updateRequest endpoint tells you nothing about what changed or whether that change was even valid, it's just a database write with a fancy name. An assignDriver endpoint, on the other hand, can enforce exactly the rules that should apply to that specific action: is the driver available, is the request in a state where assignment makes sense, does the person making the request have permission to assign drivers?
In other words, a collection request isn't just a row in a table, it's a workflow that moves through a defined sequence of states, and the API is designed to reflect that reality rather than hide it behind generic CRUD verbs.
Authentication and Authorization Model
Security in Smart Cycle is handled through JWT-based authentication with Spring Security.
Authentication Flow
1. A user registers or logs in
2. The backend validates credentials and issues a JWT
3. That token is stored in an HTTP-only cookie (not local storage, which is more vulnerable to XSS-based token theft)
4. Every subsequent request passes through Spring Security filters, which validate the token before the request is allowed to reach a controller
Security Design Principles
Domain Model: Waste Management as a Workflow System
Rather than modeling the system as a static set of database tables, Smart Cycle models it as a sequence of state transitions:
1. A resident creates a pickup request
2. An admin schedules the request and assigns resources
3. A driver executes the collection
4. The system records completion
5. Payment and rebate processing occurs
This workflow-first mindset shapes the core entities:
Each entity is designed as a participant in this broader operational sequence rather than an isolated record. A CollectionRequest, for example, isn't just a static row, it carries a status that reflects exactly where it sits in the pickup-to-payment lifecycle.
API Design: Contracts Between Frontend and Backend
Smart Cycle uses DTOs (Data Transfer Objects) as a strict boundary between the frontend and backend, rather than exposing raw JPA entities directly through the API.
Why DTOs Matter
CollectionRequest can receive different fields depending on what's relevant (and permitted) for their roleThis means React components consume exactly the data they need, nothing more, nothing less, rather than being handed an entire domain model and having to figure out which fields matter.
Real-Time Feedback Without Real-Time Complexity
It would be easy to reach for WebSockets or an event-streaming system to make Smart Cycle feel responsive. Instead, the project makes a deliberate trade-off toward simplicity:
This keeps the system's operational complexity low while still giving users a responsive experience. Real-time infrastructure like WebSockets is powerful, but it also introduces connection management, scaling considerations, and failure modes that aren't justified at this stage of the system's scale.
Styling and UI System
The interface is built with TailwindCSS, using a utility-first approach rather than hand-written custom CSS per component.
This choice provides:
Lucide React supplies a lightweight, consistent icon set, keeping the visual language coherent without adding meaningful bundle size or performance overhead.
Why Vite for Frontend Performance
Vite was chosen as the build tool and dev server for a few concrete reasons:
Backend Architecture: Why Layered Design Works Here
Microservices are often treated as the default choice for "serious" or "scalable" backend systems. Smart Cycle deliberately avoids that path in favor of a modular monolith.
Why Not Microservices?
Instead, the layered monolith architecture provides:
Key Backend Technologies
Database Design Overview
The database schema is structured around operational entities, not just isolated, independently designed tables. Core models include:
Every table is designed with its place in the broader operational workflow in mind, for example, the scheduling tables are built to connect naturally to both collection requests and vehicle/route assignment, rather than existing as disconnected reference data.
Testing Strategy
The backend testing strategy covers three layers:
Together, these tests protect three things: business logic correctness, API stability, and consistent enforcement of security rules across the system.
Full-Stack Integration Philosophy
It's worth stating plainly: Smart Cycle is not "a React app with a Spring Boot API bolted on." It is designed and reasoned about as one system split across two layers, where each layer has a clear and non-overlapping set of responsibilities.
Frontend Responsibilities
Backend Responsibilities
Because these responsibilities are cleanly separated, neither layer can function correctly on its own, which is intentional. It forces architectural discipline: the frontend can never assume it's the source of truth for what's allowed, and the backend never has to guess at what the user intended, because the API contract (via DTOs and action-based endpoints) makes intent explicit.
What This System Represents
None of the individual technologies in Smart Cycle, React, Spring Boot, MySQL, TailwindCSS, are unusual or cutting-edge on their own. The engineering value of the project isn't in tool selection; it's in how those tools were assembled to solve a genuinely awkward problem: coordinating four different types of users around one shared, evolving set of real-world operations.
The value lies specifically in:
Conclusion
Building Smart Cycle required more than picking a tech stack off a shelf. It required designing a system where multiple real-world actors, residents, drivers, recycling center operators, and administrators, could interact with shared operational workflows safely, consistently, and without stepping on each other.
The result is a full-stack architecture where:
Built for a cleaner, smarter, and more structured approach to waste management.


