Command Palette

Search for a command to run...

aadityarajvarshney4/mahesh-chandra-gupta-official-portal
Public
wasmer run aadityarajvarshney4/mahesh-chandra-gupta-official-portal

Mahesh Chandra Gupta Official Portal

A polished full-stack public-service portal for Budaun, Uttar Pradesh built with plain HTML, CSS, vanilla JavaScript, Express.js, and SQLite through sql.js.

This project intentionally does not use React, Vite, Next.js, Tailwind, or any frontend framework.

What It Includes

  • Protected civic portal pages: Home, About Budaun, Projects, Sevaks, Gallery, and Contact / Public Concern.
  • Public entry pages: Login and Register.
  • JWT login with bcrypt password hashing.
  • Role-aware access with user and admin accounts.
  • Remember-me behavior using localStorage; session-only login using sessionStorage.
  • Frontend auth guard with logout, /api/auth/me token verification, admin badges, and admin-only controls.
  • REST API routes for auth, projects, sevaks, gallery, seva works, concerns, mandals, and villages.
  • SQLite database file stored at server/data/portal.sqlite.
  • Seed data for admin/user accounts, mandals, villages, projects, sevaks, gallery items, seva works, and public concerns.
  • Wasmer Edge config with wasmer.toml, app.yaml, health check, and /data volume path.

Local Setup

npm install
cp .env.example .env
npm run seed
npm start

Open:

http://localhost:3000

First visit behavior:

  • If you are not logged in, / redirects to /login.html.
  • Register creates an account and redirects to login.
  • Login redirects to /index.html.
  • Remember me keeps you logged in until token expiry or logout.
  • Logout clears both browser storage locations and returns to login.

Local Accounts

Admin:

admin@mcgportal.in
Admin@12345

User:

user@mcgportal.in
User@12345

Admin users can add, edit, and delete projects, gallery images, sevaks, and seva work cards. Admin users can also view submitted public concerns and update their status.

Normal users can view public portal content and submit concerns. They cannot see plus buttons, edit/delete controls, dashboard links, or admin concern tools.

Environment Variables

Copy .env.example to .env:

PORT=3000
NODE_ENV=development
DATABASE_URL=./server/data/portal.sqlite
JWT_SECRET=replace-with-a-long-random-secret
CORS_ORIGIN=*
ADMIN_SEED_PASSWORD=Admin@12345
USER_SEED_PASSWORD=User@12345

What each value means:

  • PORT: Local Express server port.
  • NODE_ENV: Use development locally and production on Wasmer.
  • DATABASE_URL: Path to the local SQLite database file.
  • JWT_SECRET: Secret used to sign login tokens.
  • CORS_ORIGIN: Allowed frontend origin. Use * locally or a specific domain in production.
  • ADMIN_SEED_PASSWORD: Password used when creating the seeded admin account.
  • USER_SEED_PASSWORD: Password used when creating the seeded normal user account.

SQLite does not require API keys. There is no database username, password, host, or cloud key for this local SQLite setup. The only database value needed is:

DATABASE_URL=./server/data/portal.sqlite

That path creates or reads a local SQLite database file.

Creating a JWT Secret

For development, use any long random string. This command creates one:

node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"

Copy the output into .env as JWT_SECRET.

Do not commit .env.

Useful Scripts

npm start
npm run dev
npm run seed
npm run seed:reset

npm run seed resets and recreates starter data. To fully reset local data manually, delete:

server/data/portal.sqlite

Then run:

npm run seed

API Routes

POST /api/auth/register
POST /api/auth/login
GET  /api/auth/me
GET  /api/projects        logged-in users
GET  /api/projects/:id    logged-in users
POST /api/projects        admin only
PUT  /api/projects/:id    admin only
DELETE /api/projects/:id  admin only
GET  /api/sevaks          logged-in users
GET  /api/sevaks/:id      logged-in users
POST /api/sevaks          admin only
PUT  /api/sevaks/:id      admin only
DELETE /api/sevaks/:id    admin only
GET  /api/gallery         logged-in users
GET  /api/gallery/:id     logged-in users
POST /api/gallery         admin only
PUT  /api/gallery/:id     admin only
DELETE /api/gallery/:id   admin only
GET  /api/works           logged-in users
GET  /api/works/:id       logged-in users
POST /api/works           admin only
PUT  /api/works/:id       admin only
DELETE /api/works/:id     admin only
POST /api/concerns        logged-in users
GET  /api/concerns/mine   current user's concern notifications
GET  /api/concerns        admin only
GET  /api/concerns/resolved admin only
GET  /api/concerns/:id    admin only
PATCH /api/concerns/:id/status admin only
GET  /api/concerns/stats  logged-in users
GET  /api/mandals
GET  /api/villages
GET  /api/health

Protected routes require:

Authorization: Bearer <jwt>

Admin-only routes also require the token user to have role: "admin".

Project Structure

public/
  index.html
  about.html
  projects.html
  sevaks.html
  gallery.html
  login.html
  register.html
  contact.html
  css/
  js/
  assets/
server/
  server.js
  config/
  routes/
  controllers/
  models/
  middleware/
  seed/
.env.example
package.json
wasmer.toml
app.yaml
README.md

Wasmer Edge Deployment

Install the Wasmer CLI and login:

wasmer login

Local preparation:

npm install
npm run seed
npm start

Wasmer test and deploy:

wasmer deploy --build-remote --non-interactive
wasmer app info aadityarajvarshney4/mcg
wasmer app logs aadityarajvarshney4/mcg

The Edge app is deployed as aadityarajvarshney4/mcg. Wasmer assigns its wasmer.app hostname; run wasmer app info after deployment to see the active URL. Store JWT_SECRET in Wasmer's app secrets, never in wasmer.toml or app.yaml.

The app mounts the Wasmer volume portal-data at /data and stores SQLite at /data/portal.sqlite. On the first boot of an empty volume, the backend creates the complete seed dataset. Later deployments preserve existing records and only restore a missing seeded admin account; they do not reset the database.

Deployment reminder:

  • Remove .git.
  • Remove node_modules.
  • Remove .env.
  • Do not upload local secrets.
  • Deploy using Wasmer CLI only after local testing.

The Wasmer config uses:

DATABASE_URL=/data/portal.sqlite

The /data path is mounted as a Wasmer volume so the SQLite file can persist. Wasmer documents app environment variables, health checks, and volumes in its official Edge configuration and persistent storage docs.

Packaging Hygiene

Do not include these in a deployment ZIP or commit:

node_modules/
.git/
.env
server/data/*.sqlite
server/data/*.sqlite-*

Use .env.example as the public template and create .env locally.

Mahesh Chandra Gupta Official Portal full-stack Express and SQLite public-service app.