FlashVote is a real-time polling platform built with ASP.NET Core on the backend and React on the frontend.
It provides:
- Poll creation and retrieval through REST endpoints.
- Real-time vote updates through SignalR.
- Live chart visualization in the web dashboard.
FlashVote is organized as a two-app monorepo:
- FlashVoteBackend: ASP.NET Core Web API, SignalR hub, EF Core, SQLite.
- FlashVoteFrontend: React + Vite app with React Query, SignalR client, Tailwind, and Recharts.
High-level flow:
- Frontend fetches polls using HTTP.
- Frontend joins a SignalR group for the active poll.
- User votes through an HTTP endpoint.
- Backend persists vote and broadcasts ReceiveVote to the poll group.
- Frontend invalidates query cache and re-fetches updated poll results.
Backend:
- ASP.NET Core (.NET 10)
- Entity Framework Core
- SQLite
- SignalR
Frontend:
- React 19 + TypeScript
- Vite
- TanStack React Query
- @microsoft/signalr
- Recharts
- TailwindCSS
- shadcn-style UI components
- FlashVoteBackend
- Controllers: REST endpoints
- Services: business logic
- Repositories: persistence abstraction
- Hubs: SignalR hub
- Data: EF DbContext
- Models: entities and DTOs
- FlashVoteFrontend
- src/services: HTTP and SignalR clients
- src/hooks: React Query and realtime hooks
- src/components: dashboard and UI components
Default local endpoints:
- Backend API: http://localhost:5000
- SignalR hub: http://localhost:5000/pollhub
- Frontend dev server: http://localhost:5173
Current backend host binding is 0.0.0.0:5000.
- .NET SDK 10
- Node.js 20+
- npm 10+
From FlashVoteBackend:
dotnet restore
dotnet build
dotnet runDevelopment OpenAPI/Swagger:
From FlashVoteFrontend:
npm install
npm run devOpen the URL shown by Vite (typically http://localhost:5173).
The frontend reads backend base URL from:
- VITE_API_BASE_URL
Example FlashVoteFrontend/.env:
VITE_API_BASE_URL=http://localhost:5000If not defined, frontend falls back to the default value in the HTTP client.
Base route:
- /api/poll
Endpoints:
- GET /api/poll
- Returns all polls (summary list).
- GET /api/poll/{id}
- Returns one poll with options and vote counts.
- POST /api/poll
- Creates a poll from CreatePollDto.
- POST /api/poll/{pollId}/vote/{optionId}
- Registers a vote and returns success status.
Hub endpoint:
- /pollhub
Hub methods:
- JoinPoll(string pollId)
- LeavePoll(string pollId)
Server-to-client event:
- ReceiveVote(optionId)
Poll:
- Id: Guid
- Title: string
- Description: string
- CreatedAt: DateTime
- ExpiresAt: DateTime?
- IsClosed: bool
- Options: List
Option:
- Id: Guid
- Text: string
- VoteCount: int
- PollId: Guid
Current backend CORS policy allows any origin with credentials for development convenience.
Important:
- This is not recommended for production.
- In production, restrict origins explicitly and enforce HTTPS.
Useful backend commands:
dotnet build
dotnet watch run
dotnet ef database updateUseful frontend commands:
npm run lint
npm run build
npm run previewManual validation flow:
- Start backend.
- Start frontend.
- Open the app in two browser tabs.
- Select the same poll in both tabs.
- Vote in tab A.
- Confirm charts and vote counts refresh in tab B without reload.
- Confirm backend is running on the expected host/port.
- Confirm VITE_API_BASE_URL points to the active backend.
- Confirm frontend connects to /pollhub.
- Confirm active poll triggers JoinPoll.
- Confirm vote endpoint returns success.
- Recharts and SignalR increase bundle size.
- Consider route-based code splitting for optimization.
Implemented:
- Real-time poll visualization dashboard.
- Vote submission from frontend.
- SignalR-driven synchronization.
- Tailwind + shadcn-style UI foundation.
Not implemented yet:
- Authentication/authorization.
- Full poll admin workflow in frontend.
- Automated end-to-end test suite.