Solar-Tracker-System: A Tiny Workflow Engine for Solar Installations

A resident submits a request, an admin routes it, and an installer gets attached. Under the surface, this repo is a study in how to model service operations with Spring Boot and React.

8 min read • View on GitHub • More from ganeshpawar27

A rooftop solar panel is linked by a paper-trail of request cards to an admin desk, then to an installer carrying a tool case. The image explains that the product is not about tracking sunlight, but about moving a work order through a service workflow.
The real object in this system is the request. Everything else exists to move it from submission to assignment.
Key Takeaways

A Solar Request Becomes a Work Order

The most interesting thing in this repo is not the stack. It is the shape of the business logic. A resident submits a solar request, an admin reviews it, and an installer gets assigned. That is a work-order pipeline, not a generic dashboard.

Seen that way, the app is smaller than it first appears and more opinionated than most CRUD systems. It encodes a service business in three roles and a status trail: Pending, then Assigned, then completion.

A request moves across three roles. The diagram makes the hidden state machine visible.

That framing matters because it explains why the frontend and backend are organized the way they are. The UI is not trying to be a platform. It is trying to keep one operational object moving through a narrow lane.


The Data Model Is the Real Product

The backend centers on three entities: Resident, Installer, and InstallationRequest. The first two describe who people are. The third describes the work that exists.

Two contact cards labeled Resident and Installer sit beside a stamped request ticket. The contact cards carry handwritten contactId tags, while the request ticket has its own auto-generated numeric ID and a progression of status stamps. The image explains the split between identity and work in the data model.
The unusual part is not that there are IDs. It is that people and requests do not share the same identity strategy.

That split is the key design tell. Residents and installers use manually assigned contactId values, while requests use auto-generated IDs. In practice, that means the system treats contact identity as something external or stable, while requests are internal transactional objects.

Model choiceWhat it suggestsWhy it matters
Manual contact IDs for residents and installersIdentity comes from a controlled registry or an external conventionThe app can link people without forcing every record to be auto-generated
Auto-generated request IDsThe request is an internal work orderEach application gets its own lifecycle and audit trail
Many-to-one links from request to resident and installerOne resident can own many requests, and one installer can be attached laterThe schema matches how assignment actually works

That is a better model than putting everything into one table with a status column. It keeps the workflow legible, and it makes later assignment possible without rewriting the record shape.


The Admin Dashboard Chooses Guidance Over Speed

The admin side is the most human part of the app. Instead of dropping the user into a dense control surface, adminDashboard.jsx starts in a help state. That is a small choice with a clear message: learn the system first, operate it second.

The view-switching pattern is simple. A single state variable decides whether the admin sees residents, installers, pending requests, or guidance. The result is a command center with guardrails, not a maze of tabs.

This is a simple Solar Tracker System using Arduino Uno and LDR sensors.

Ganesh Pawar, Project Creator · Project README

Even though that README line describes a different kind of project, it still captures the tone of the repository: a teaching artifact that prefers clarity over ceremony. The code reads like it was meant to be understood by the next person, not just executed by them.


How the Backend Moves State

The request lifecycle lives in RequestService. The important methods are straightforward: applyForSolar creates the request and marks it Pending, then assignInstaller attaches an installer and advances the state to Assigned.

public InstallationRequest applyForSolar(InstallationRequest request) {
    request.setStatus("Pending");
    return requestRepository.save(request);
}

public InstallationRequest assignInstaller(Long requestId, Long installerId) {
    InstallationRequest request = requestRepository.findById(requestId)
        .orElseThrow();
    Installer installer = installerRepository.findById(installerId)
        .orElseThrow();

    request.setInstaller(installer);
    request.setStatus("Assigned");
    return requestRepository.save(request);
}

The query layer is just as revealing. Spring Data method-name derivation keeps the repository thin, so the service can ask for things like requests by resident contact ID without writing custom SQL. That is exactly what you want in a compact workflow app: clear intent, minimal ceremony.

This is where the repo stops looking like a form app. The service layer is acting like a dispatcher, and the request row is the thing being dispatched.


Why the Frontend Feels Centralized

The React app is organized around a few explicit control surfaces. App.jsx uses nested routing so a resident dashboard can keep its shell while swapping views. The backend API is accessed through a centralized Axios instance, which keeps the network layer from leaking through the component tree.

That structure is boring in the best way. It means each screen has a job, and the application does not need a sprawling component hierarchy to feel coherent.

LayerGeneric CRUD appThis repoMature workflow platform
RoutingFlat pages and loose navigationNested routes and persistent dashboard layoutRole-aware surfaces with preserved context
Admin modelTables and formsHelp-first command center with view switchingTask queues, filters, and SLA tools
Data shapeRecords with status flagsRequests as work orders linked to peopleEvent history, permissions, and auditing
IntegrationAd hoc fetch callsCentral Axios configurationTyped API clients and policy layers

The difference is not visual polish. It is control. The app keeps the number of places you can act very small, which is exactly what a workflow tool should do.


What This Repo Is Good For, and What It Is Not

As a learning project, this is solid. It demonstrates role separation, request routing, relationship modeling, and a service layer that changes state in a disciplined way. If you are building a niche operations tool, the pattern is useful.

It is not production software. Password handling is plain-string level in the research notes, the security story is thin, and the deployment hardening is not there. The structure is there. The safeguards are not.

Use caseFitWhy
Student project or teaching exampleStrongThe code shows the full request lifecycle without unnecessary complexity
Early internal prototypeModerateThe workflow is clear, but security and validation need work
Production service platformWeakMissing authentication hardening, hashing, and operational safeguards

That gap is not a failure. It is what makes the repo legible. You can see the business shape without the noise of a mature system.


The Pattern Behind the Project

The real lesson here is reusable. Any small service marketplace can borrow this shape: request, triage, assignment, status, and role-based views. Once you model the work order cleanly, the rest of the product becomes easier to reason about.

That is why this repository stands out. It is not trying to be everything. It is showing how to turn a narrow service business into software without losing the shape of the business.