Academic context: Project for the Software Architecture subject at SENA (Servicio Nacional de Aprendizaje).
Find lost pets using QR codes attached to their collars. When someone scans a pet’s QR code, they see the owner’s contact info to reach out—no account required for guests.
- Owner registration and JWT-based login
- Owners register pets and generate a unique QR for each
- Public (guest) view via QR; no login required
- MySQL persistence
- Node.js + Express backend
- Ready to deploy on Vercel serverless
- Runtime: Node.js
- Web framework: Express
- Auth: JSON Web Tokens (JWT)
- Database: MySQL
- QR codes: Open-source QR library (e.g.,
qrcode) - Deployment: Vercel
- Owner user creates an account and logs in.
- Owner registers one or more pets; each pet gets a unique QR ID and URL.
- Anyone who finds a pet scans the QR and sees the owner’s contact details (read-only, no login).
- POST /api/auth/register — create owner account
- POST /api/auth/login — authenticate, returns JWT
- GET /api/pets — list owner’s pets (auth)
- POST /api/pets — create a pet and generate QR (auth)
- GET /p/:qrId — public pet contact view (no auth)
Create a .env file with values like:
# App
NODE_ENV=development
PORT=3000
JWT_SECRET=replace-with-a-long-random-secret
APP_BASE_URL=https://your-domain.example # used in QR deep links
# MySQL
MYSQL_HOST=localhost
MYSQL_PORT=3306
MYSQL_USER=petfinder
MYSQL_PASSWORD=petfinder_password
MYSQL_DATABASE=petfinder
On Vercel, set these in Project Settings → Environment Variables.
-- users (owners)
CREATE TABLE users (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(120) NOT NULL,
email VARCHAR(190) NOT NULL UNIQUE,
password_hash VARCHAR(255) NOT NULL,
phone VARCHAR(40),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- pets
CREATE TABLE pets (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
owner_id BIGINT NOT NULL,
name VARCHAR(120) NOT NULL,
species VARCHAR(60),
breed VARCHAR(120),
color VARCHAR(120),
qr_id VARCHAR(64) NOT NULL UNIQUE, -- short code embedded in the QR URL
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (owner_id) REFERENCES users(id)
);
src/
server.ts|js
routes/
controllers/
middleware/
services/
db/
utils/qr.ts|js
public/
- Use a single Express handler exported for serverless.
- Add environment variables in Vercel.
- Example
vercel.json(adjust paths as you scaffold the app):
{
"functions": { "api/index.js": { "runtime": "@vercel/node@latest" } },
"routes": [
{ "src": "/api/(.*)", "dest": "/api/index.js" },
{ "src": "/p/(.*)", "dest": "/api/index.js" }
]
}
- Scaffold the Node.js + Express app and wire routes.
- Implement JWT auth and owner-only pet management.
- Integrate a QR library to generate codes that point to
/p/:qrId. - Add tests and CI, then deploy to Vercel.
Open to contributions. Please propose changes via pull request.
- Copy the example env and edit values:
cp .env.example .env
notepad .env
- Ensure MySQL is running and the user/database exist. Create them if needed:
mysql -u root -p -e "CREATE DATABASE IF NOT EXISTS petfinder; CREATE USER IF NOT EXISTS 'petfinder'@'%' IDENTIFIED BY 'petfinder_password'; GRANT ALL PRIVILEGES ON petfinder.* TO 'petfinder'@'%'; FLUSH PRIVILEGES;"
- Install deps and apply the schema:
npm install
npm run db:init
- Start the server:
npm start
If you receive an access denied from MySQL during db:init, verify .env credentials match your local MySQL setup.
This project is distributed under a Restricted Use License intended for academic/demonstration purposes (SENA) and non-commercial testing only. Commercial use, redistribution, sublicensing, or rebranding is not permitted without prior written consent from the author.
See the full text in LICENSE.