How vkantb05/voting-app-backend-ejs works
1. High-level shape
This is a server-rendered Node.js voting application, not a client-side SPA. The main architecture is an Express app that renders EJS pages, persists data in MongoDB, and uses auth/session logic to separate voters from admins.
2. Entry point and app composition
server.js is the runtime entry point. It likely wires together Express middleware, connects to the database via db.js, mounts the route modules, serves static assets from public/, and starts listening on the configured port.
3. Persistence boundary
MongoDB is the only visible data store. The models/ folder contains two data models: user.js and candidate.js. That strongly suggests two core collections:
- users for accounts, roles, and voting state
- candidates for election entries and vote counts or related metadata
4. Authentication and authorization
jwt.js plus the README’s mention of sessions and bcrypt indicate the app has an auth layer for login/signup and protected routes. Access is role-based: admins can manage candidates, while voters can browse and cast a vote. The architecture likely enforces this at the route level rather than in a separate service.
5. Route boundaries
The application is split into two main route groups:
- routes/UserRoute.js for signup, login, profile editing, and user-facing account flows
- routes/CandidateRoute.js for candidate CRUD, voting actions, and results
These route modules act as the main application boundary between HTTP requests and model operations.
6. Server-side presentation
The views/ directory contains EJS templates for all primary screens: login, signup, profile, edit profile, candidate management, voting, results, and confirmation states like voted. This indicates the UI is generated on the server and the browser receives HTML pages, not an API-first frontend.
7. Static assets
public/stylesheet/style.css is the only obvious frontend asset pipeline. Styling is handled by static CSS served directly by Express. There is no evidence of a build step, frontend framework, or component bundler.
8. Core data flows
The main request flows are:
- user registers or logs in
- server authenticates the user and establishes session/auth state
- voter browses candidates and submits one vote
- admin creates/edits/deletes candidates and checks results
- app reads/writes MongoDB through the models and renders the next EJS view
9. Voting rule enforcement
A key business boundary is the “one vote per user” rule described in the README. That logic likely lives in the candidate/user route handling and user model state, making it an application-level constraint rather than a database-only rule.
10. Operational/runtime concerns
The README shows environment-driven deployment with PORT, MONGO_URI, and SESSION_SECRET. That implies the app is built to run the same way locally and in cloud deployment environments such as Render or Railway, with configuration injected at runtime.
11. What is notably absent
There is no evidence of separate controllers, services, background jobs, queues, or real-time sockets. The architecture appears intentionally compact: routes + models + views + static assets, with authentication and persistence handled inside the same Node/Express process.
12. How to draw the diagram
A good architecture diagram would show:
- browser/client on the left
- Express app in the middle
- route modules branching into user and candidate flows
- EJS rendering back to the browser
- MongoDB on the data side through db.js and the models
- public/ as a static asset path served directly by the app
- auth/session/JWT logic as a cross-cutting concern around protected routes
Main entry points: server.js App entry · UserRoute.js User routes · CandidateRoute.js Candidate routes · jwt.js Auth layer
Components 16
Client
Browser-side request and page consumption
- Browser · User agent that receives rendered HTML and submits forms
App runtime
Express entry point and cross-cutting middleware
- App entry · Wires middleware, routes, static assets, and server startup
server.js - DB connect · Creates and manages the MongoDB connection
db.js - Auth layer · Handles login state and route protection
jwt.js
HTTP routes
Request handlers for account and voting flows
- User routes · Signup, login, profile, and account flows
routes/UserRoute.js - Candidate routes · Candidate management, voting, and results flows
routes/CandidateRoute.js
Data layer
MongoDB connection and collections
- User model · Accounts, roles, and vote-state records
models/user.js - Candidate model · Candidates and vote-related records
models/candidate.js - MongoDB · Primary persistent data store
Server views
EJS pages rendered by the app
- Login page · Sign-in screen rendered by the server
views/login.ejs - Signup page · Account creation screen rendered by the server
views/signup.ejs - Profile page · User account summary and profile screen
views/profile.ejs - Candidates page · Candidate listing and voting interface
views/candidate.ejs - Results page · Vote totals and election outcome screen
views/result.ejs - Voted page · Confirmation shown after a successful vote
views/voted.ejs
Static assets
Directly served CSS
- Stylesheet · Global presentation styling served directly
public/stylesheet/style.css
Connections 19
- Browser → App entry: HTTP requests · Browser submits form posts and page requests to the Express app
- App entry → DB connect: connects · Bootstraps the database connection during startup
- App entry → Auth layer: uses auth · Applies auth/session handling across protected routes
- App entry → User routes: mounts · Registers the user-facing route module
- App entry → Candidate routes: mounts · Registers the candidate and voting route module
- App entry → Stylesheet: serves · Exposes static CSS assets to the browser
- User routes → Auth layer: protects · Uses auth checks for login and profile flow
- Candidate routes → Auth layer: protects · Uses auth checks for voting and admin actions
- User routes → User model: reads/writes · Creates accounts and updates user state
- Candidate routes → Candidate model: reads/writes · Manages candidates and vote data
- User model → MongoDB: persists · Stores user documents in MongoDB
- Candidate model → MongoDB: persists · Stores candidate documents in MongoDB
- User routes → Login page: renders · Returns the login page
- User routes → Signup page: renders · Returns the signup page
- User routes → Profile page: renders · Returns the profile page
- Candidate routes → Candidates page: renders · Returns the candidate browsing and voting page
- Candidate routes → Results page: renders · Returns election results
- Candidate routes → Voted page: renders · Returns vote confirmation after submission
- App entry → Browser: HTML response · Sends rendered pages back to the client