k4njoe
v1.0.0
Published
A simple sus package with comprehensive exam reference for Sequelize CLI, React Hooks, API Gateway, and Express.
Maintainers
Readme
ඞ sus-package
A minimalist Node.js package containing the sus.js module, bundled with a complete, zero-memorization practical reference guide covering Sequelize CLI with XAMPP MySQL, React Hooks, API Gateway, and Express Server.
🚀 Quick Start: sus.js
Run directly:
node sus.js
# Output:
# susOr import as a module:
const sus = require('./sus');
sus(); // Prints "sus"📚 EXAM CRUNCH REFERENCE GUIDE
1. 🗄️ Sequelize CLI Bank Database (MySQL / XAMPP)
🎯 The Question Requirements
- Create a Bank database.
- Create a Customer model:
id: Auto-increment integer primary keyname: Maximum length 15,allowNull: falseaddress:allowNull: falsecontact_no:allowNull: false
- Create an Account model:
customerId: Foreign key referencing Customeraccount_type: String (e.g., Savings, Current)balance: Float / Decimal
- Build a One-to-One relationship between
CustomerandAccount. - Implement using Sequelize CLI and MySQL Server (XAMPP).
🛠️ Step-by-Step Execution Plan
Step 0: Start XAMPP
- Open XAMPP Control Panel.
- Click Start for Apache and MySQL (both turn green).
- MySQL default host:
127.0.0.1, user:root, password:""(empty), port:3306.
Step 1: Initialize Project & Install Packages
mkdir bank_project && cd bank_project
npm init -y
npm install sequelize mysql2 cors express
npm install --save-dev sequelize-cliStep 2: Initialize Sequelize CLI
npx sequelize-cli initThis automatically generates 4 folders:
config/(containsconfig.json)models/(containsindex.js)migrations/seeders/
Step 3: Configure Database in config/config.json
Open config/config.json and edit the development block:
{
"development": {
"username": "root",
"password": null,
"database": "bank_db",
"host": "127.0.0.1",
"dialect": "mysql"
}
}Step 4: Create Database via CLI
npx sequelize-cli db:create(Creates bank_db in MySQL server automatically)
Step 5: Generate Models via CLI
npx sequelize-cli model:generate --name Customer --attributes name:string,address:string,contact_no:string
npx sequelize-cli model:generate --name Account --attributes customerId:integer,account_type:string,balance:floatStep 6: Define Constraints & 1-to-1 Associations in Models
models/customer.js:
'use strict';
const { Model } = require('sequelize');
module.exports = (sequelize, DataTypes) => {
class Customer extends Model {
static associate(models) {
// ONE-TO-ONE: Customer hasOne Account
Customer.hasOne(models.Account, {
foreignKey: 'customerId',
as: 'account',
onDelete: 'CASCADE'
});
}
}
Customer.init({
name: {
type: DataTypes.STRING(15), // Max length 15
allowNull: false // Not null
},
address: {
type: DataTypes.STRING,
allowNull: false // Not null
},
contact_no: {
type: DataTypes.STRING,
allowNull: false // Not null
}
}, {
sequelize,
modelName: 'Customer',
});
return Customer;
};models/account.js:
'use strict';
const { Model } = require('sequelize');
module.exports = (sequelize, DataTypes) => {
class Account extends Model {
static associate(models) {
// ONE-TO-ONE: Account belongsTo Customer
Account.belongsTo(models.Customer, {
foreignKey: 'customerId',
as: 'customer'
});
}
}
Account.init({
customerId: {
type: DataTypes.INTEGER,
allowNull: false,
unique: true // Guarantees strict 1-to-1
},
account_type: {
type: DataTypes.STRING,
allowNull: false
},
balance: {
type: DataTypes.FLOAT,
defaultValue: 0.0
}
}, {
sequelize,
modelName: 'Account',
});
return Account;
};Step 7: Run Migrations
npx sequelize-cli db:migrateStep 8: Verify & Test (testBank.js)
const { Customer, Account, sequelize } = require('./models');
async function testBank() {
try {
await sequelize.authenticate();
console.log('✅ Connected to MySQL via Sequelize CLI!');
// Create Customer with nested 1-to-1 Account
const newCustomer = await Customer.create({
name: 'Sarah Connor',
address: '42 Wallaby Way',
contact_no: '9876543210',
account: {
account_type: 'Savings',
balance: 75000.50
}
}, {
include: [{ model: Account, as: 'account' }]
});
console.log('✅ Inserted Customer with Account:');
console.log(`ID: ${newCustomer.id} | Name: ${newCustomer.name} | Balance: ₹${newCustomer.account.balance}`);
// Query back from MySQL with association
const fetched = await Customer.findByPk(newCustomer.id, {
include: [{ model: Account, as: 'account' }]
});
console.log('✅ Queried from DB:', fetched.toJSON());
process.exit(0);
} catch (err) {
console.error('❌ Error:', err.message);
process.exit(1);
}
}
testBank();Run test:
node testBank.js2. ⚛️ The 6 Core React Hooks Demonstration
🧠 The Mental Model Matrix
| Hook | What it does | Real-world example |
|---|---|---|
| useState | Holds reactive variable | Form input, counter |
| useEffect | Runs on mount or when dependency changes | Fetching data from API |
| useRef | Direct reference to a DOM input (no re-render) | Focusing an input field |
| useReducer | Structured state machine | Complex action dispatching |
| useMemo | Caches heavy calculation | Expensive math calculation |
| useContext | Shared global state | App theme, logged-in user |
💻 Master All-in-One Component (SixHooksDemo.jsx)
import React, { useState, useEffect, useRef, useReducer, useMemo, useContext, createContext } from 'react';
// 1. Create Context for global theme
const ThemeContext = createContext();
// 2. Reducer function for useReducer
function countReducer(state, action) {
switch (action.type) {
case 'inc': return { count: state.count + 1 };
case 'dec': return { count: state.count - 1 };
default: return state;
}
}
export default function SixHooksDemo() {
// Hook 1: useState
const [num, setNum] = useState(5);
// Hook 2: useRef (holds direct DOM pointer)
const inputRef = useRef();
// Hook 3: useReducer
const [state, dispatch] = useReducer(countReducer, { count: 0 });
// Hook 4: useEffect (triggers when state.count changes)
useEffect(() => {
console.log("Count changed to:", state.count);
}, [state.count]);
// Hook 5: useMemo (caches calculation until num changes)
const squaredVal = useMemo(() => {
return num * num;
}, [num]);
return (
<ThemeContext.Provider value={{ color: '#0284c7' }}>
<div style={{ padding: '20px', fontFamily: 'sans-serif' }}>
<h2>React 6 Core Hooks Master Demo</h2>
{/* 1. useState & 2. useRef */}
<input
ref={inputRef}
type="number"
value={num}
onChange={(e) => setNum(Number(e.target.value))}
/>
<button onClick={() => inputRef.current.focus()} style={{ marginLeft: '10px' }}>
Focus Input (useRef)
</button>
{/* 5. useMemo result */}
<p>Square of {num} (useMemo): <strong>{squaredVal}</strong></p>
{/* 3. useReducer */}
<p>Reducer Counter: <strong>{state.count}</strong></p>
<button onClick={() => dispatch({ type: 'inc' })}>+</button>
<button onClick={() => dispatch({ type: 'dec' })} style={{ marginLeft: '5px' }}>-</button>
{/* 6. useContext Consumer */}
<ChildWithContext />
</div>
</ThemeContext.Provider>
);
}
function ChildWithContext() {
// Hook 6: useContext
const theme = useContext(ThemeContext);
return (
<p style={{ color: theme.color, marginTop: '20px' }}>
This line styled using <strong>useContext</strong> theme!
</p>
);
}3. 🚪 API Gateway to Route Requests (service1 & service2)
🧠 The Mental Model
The client only talks to port 3000 (Gateway).
The Gateway forwards requests using Node's built-in fetch():
- Client requests
http://localhost:3000/service1$\to$ Gateway fetches from3001 - Client requests
http://localhost:3000/service2$\to$ Gateway fetches from3002
💻 The 3 Files:
File 1: service1.js (Port 3001)
const express = require('express');
const app = express();
app.get('/', (req, res) => {
res.json({ service: "Service 1", message: "Users Microservice active" });
});
app.listen(3001, () => console.log("Service 1 live on port 3001"));File 2: service2.js (Port 3002)
const express = require('express');
const app = express();
app.get('/', (req, res) => {
res.json({ service: "Service 2", message: "Orders Microservice active" });
});
app.listen(3002, () => console.log("Service 2 live on port 3002"));File 3: gateway.js (Port 3000)
const express = require('express');
const app = express();
// Route to Service 1
app.get('/service1', async (req, res) => {
try {
const response = await fetch('http://localhost:3001');
const data = await response.json();
res.json(data);
} catch (err) {
res.status(502).json({ error: "Service 1 is unreachable" });
}
});
// Route to Service 2
app.get('/service2', async (req, res) => {
try {
const response = await fetch('http://localhost:3002');
const data = await response.json();
res.json(data);
} catch (err) {
res.status(502).json({ error: "Service 2 is unreachable" });
}
});
app.listen(3000, () => console.log("🚪 Gateway live on port 3000"));⚡ Verification:
Open 3 terminals:
node service1.jsnode service2.jsnode gateway.js
Visit http://localhost:3000/service1 and http://localhost:3000/service2.
4. 🌐 Full Express Server Example (Sequelize + REST API)
💻 server.js
const express = require('express');
const cors = require('cors');
const { Customer, Account, sequelize } = require('./models');
const app = express();
const PORT = 5000;
// Essential Middleware
app.use(cors()); // Allows React app on port 5173/3000 to call API
app.use(express.json()); // Parses JSON request bodies
// 1. GET: Fetch all customers with their associated 1:1 account
app.get('/api/customers', async (req, res) => {
try {
const customers = await Customer.findAll({
include: [{ model: Account, as: 'account' }]
});
res.json(customers);
} catch (err) {
res.status(500).json({ error: err.message });
}
});
// 2. POST: Create new customer and linked account
app.post('/api/customers', async (req, res) => {
try {
const { name, address, contact_no, account_type, balance } = req.body;
if (!name || name.length > 15) {
return res.status(400).json({ error: "Name is required and must be max 15 characters." });
}
// Create Customer
const customer = await Customer.create({ name, address, contact_no });
// Create linked 1:1 Account
const account = await Account.create({
customerId: customer.id,
account_type: account_type || 'Savings',
balance: parseFloat(balance) || 0.0
});
res.status(201).json({ customer, account });
} catch (err) {
res.status(500).json({ error: err.message });
}
});
// 3. Start Server & Verify MySQL Connection
app.listen(PORT, async () => {
console.log(`🚀 Express server running on http://localhost:${PORT}`);
try {
await sequelize.authenticate();
console.log('✅ Connected to XAMPP MySQL database successfully!');
} catch (err) {
console.error('❌ Database connection failed:', err.message);
}
});🎯 Exam Cheat Matrix
| Question | Mental Model Anchor | Code Snippet |
|---|---|---|
| Sequelize CLI | init -> db:create -> model:generate -> db:migrate | Customer.hasOne(Account, { foreignKey: 'customerId', as: 'account' }) |
| MySQL (XAMPP) | Apache & MySQL running on 3306 | config/config.json: user root, password null, dialect mysql |
| API Gateway | Port 3000 acts as middleman | app.get('/service1', async (req, res) => res.json(await (await fetch('http://localhost:3001')).json())) |
| React Hooks | 6 hooks: state, effect, ref, reducer, memo, context | useState(val), useEffect(fn, [deps]), useRef(), useReducer(red, init) |
| Express API | cors() + express.json() + REST endpoints | app.get('/api', handler) and app.post('/api', handler) |
