Learning Journey - hokumcangus/taste-of-aloha GitHub Wiki
π Learning Journey: Taste of Aloha "It's not about knowing everythingβit's about knowing how to figure things out."
This project serves as an educational milestone in mastering the complexities of modern full-stack development, transitioning from a fragmented initial state to a professional, scalable monorepo.
π§ Key Architectural Pillars During this sprint, I focused on three major concepts that define high-level engineering:
Monorepo Management: Learning to orchestrate multiple applications (apps/web and apps/backend) within a single repository to ensure shared configurations and unified deployments.
Schema Evolution: Navigating the "real-world" process of database refactoring. Moving from separate Snack and Menu models to a unified MenuItem system taught me how to build more flexible, category-based API controllers.
State Persistence: Bridging the gap between a PostgreSQL database and a React frontend to handle complex logic, such as a persistent Shopping Cart.
π Project Evolution & Refactoring To improve the "Signal-to-Noise" ratio of the codebase, I performed the following high-impact refactors:
Doc Consolidation: Offloaded long-form guides to this Wiki to reduce repository bloat.
Standardization: Unified API naming conventions (e.g., standardizing on menuItem instead of snack) to improve code readability.
Developer Experience (DX): Implemented a Docker-based "Quick Start" workflow to lower the barrier for contributors.
π Decision Log: Why the Wiki? I chose to move long-form documentation here to keep Pull Requests strictly focused on code changes. A lean repo allows reviewers to focus on logic and quality, while this Wiki provides the "Big Picture" context.# Learning Guide: Building Taste of Aloha
This guide walks you through the development journey of Taste of Aloha, explaining what was done, why it matters, and how to continue building the application. Use this as both a reference and a roadmap for your learning.
- Development Environment Setup
- Database Setup: PostgreSQL & Prisma
- Frontend Foundation
- Backend Foundation
- Docker & Containerization
- Routing & Navigation
- UI/UX Features
- Next Steps: Order System
- Learning Resources
- Status: β Complete (v24.11.0 installed)
-
Verification: Run
node --version - Why: Node.js is the JavaScript runtime that executes both your backend server and build tools (Vite, npm)
- Status: β Complete
-
Verification: Run
docker ps - Why: Docker enables consistent development/production environments and simplifies database management
Understand Node.js versions:
- LTS (Long Term Support) versions are stable and recommended for production
- You're running v24.11.0 which is the latest LTS
-
nvm(Node Version Manager) helps manage multiple Node versions if needed
Understand Docker basics:
- Images: Blueprint for containers (like a class in OOP)
- Containers: Running instances of images (like objects/instances)
- Volumes: Persistent data storage that survives container restarts
- Networks: Allow containers to communicate with each other
# Node.js
node --version # Check Node version
npm --version # Check npm version
npm install # Install dependencies from package.json
npm run dev # Run development server
npm run build # Build for production
# Docker
docker ps # List running containers
docker ps -a # List all containers (including stopped)
docker images # List available images
docker logs <container> # View container logs
docker exec -it <container> sh # Enter container shell- Status: β Complete (v18 installed)
-
Verification: Run
psql --version - Why: PostgreSQL is a robust, reliable SQL database for storing all your application data (menu items, orders, users)
- Status: β Complete
-
Location:
apps/backend/prisma/ -
Installation:
npm install prisma @prisma/client pg -
Database Connection: Configured in
apps/backend/.env
- Status: β Complete
-
File:
apps/backend/prisma/schema.prisma -
Migration:
20251214184223_initapplied successfully -
Table:
Menutable created intaste_of_alohadatabase
PostgreSQL vs Prisma - Key Difference:
- PostgreSQL: The actual database engine that STORES your data on disk
- Prisma: A tool (ORM - Object Relational Mapping) that lets your Node.js app talk to PostgreSQL
Think of it like:
- PostgreSQL = the filing cabinet (stores data)
- Prisma = the librarian (retrieves/organizes data for you)
Architecture Flow:
Your Backend Code
β
Prisma Client (generates queries)
β
PostgreSQL Database (stores/retrieves data)
How Prisma Works:
-
Define Schema - You write
schema.prismadescribing your database tables -
Generate Migrations -
npx prisma migrate devcreates SQL migration files - Apply Migrations - SQL commands run against PostgreSQL to create/modify tables
-
Generate Client -
npx prisma generatecreates JavaScript methods you use in your code
Example Menu Model:
model Menu {
id Int @id @default(autoincrement()) // Auto-incrementing primary key
name String // Menu item name
description String // What it is
price Float // Cost in dollars
image String? // Optional image URL
category String // Type: appetizer, main, dessert
isAvailable Boolean @default(true) // Is it available to order?
createdAt DateTime @default(now()) // Timestamp when created
updatedAt DateTime @updatedAt // Timestamp when last updated
}Using Prisma in Your Code:
const { PrismaClient } = require('@prisma/client');
const prisma = new PrismaClient();
// Create a menu item
await prisma.menu.create({
data: {
name: "Spam Musubi",
description: "Spam and egg wrapped in rice",
price: 5.99,
category: "main",
image: "spam-musubi.jpg"
}
});
// Get all menu items
const allItems = await prisma.menu.findMany();
// Get one item
const item = await prisma.menu.findUnique({
where: { id: 1 }
});
// Update item
await prisma.menu.update({
where: { id: 1 },
data: { price: 6.99 }
});
// Delete item
await prisma.menu.delete({
where: { id: 1 }
});# Database commands (run from apps/backend/)
psql -U postgres # Connect to PostgreSQL
CREATE DATABASE taste_of_aloha; # Create database (in psql)
\q # Exit psql
# Prisma commands
npx prisma migrate dev --name <name> # Create and apply migration
npx prisma migrate reset # Reset database (delete all data)
npx prisma generate # Regenerate Prisma Client
npx prisma studio # Open visual database browser
npx prisma db seed # Seed database with test dataConnection String (in .env):
DATABASE_URL="postgresql://postgres:tasteofalohadb@localhost:5432/taste_of_aloha"
Tables Created:
-
Menu- Stores all menu items
Tables Not Yet Created (for Phase 1):
-
User- Customer information -
Order- Order records -
OrderItem- Individual items in each order
- Status: β Complete
-
Location:
apps/web/ -
Verification:
npm run devserves site at http://localhost:5173 - Dev Server: Running successfully with hot reload
- Status: β Complete
-
Configuration:
tailwind.config.cjs,postcss.config.js -
Syntax: Uses modern
@import "tailwindcss";inindex.css
- Status: β Complete
-
Routes: Home (
/), Menu (/menu), About (/about) - Navigation: Sticky header with client-side routing
Why Vite over Create React App:
- Speed: Vite uses native ES modules for instant HMR (Hot Module Replacement)
- Build performance: Uses esbuild which is 10-100x faster than Webpack
- Modern: Built for modern browsers, outputs optimized ES2015+ code
- Configuration: Simpler configuration than Webpack
React Fundamentals You're Using:
// Functional components (modern React)
function Home() {
return <div>Content</div>;
}
// Hooks for state management
const [isMobile, setIsMobile] = useState(false);
// Side effects (window events, API calls)
useEffect(() => {
// Runs after component mounts
}, []);
// Event handlers
const handleClick = () => { /* logic */ };Tailwind CSS Utility-First Approach:
- Instead of writing CSS classes, use utility classes:
bg-blue-500,text-white,p-4 - Responsive design with prefixes:
md:text-xl,lg:flex-row - Custom values:
bg-black/50(50% opacity black) - Why: Faster development, smaller CSS bundle, no naming conflicts
apps/web/
βββ src/
β βββ main.jsx # Entry point, renders <App />
β βββ App.jsx # Root component with BrowserRouter
β βββ index.css # Global styles, Tailwind import
β βββ pages/ # Route components
β β βββ Home.jsx # Homepage with video background
β β βββ Menu.jsx # Menu page (displays menu items)
β β βββ About.jsx # About page
β βββ components/ # Reusable UI components
β βββ services/ # API communication layer
β β βββ menuService.js
β βββ store/ # Redux state management
β β βββ slices/
β βββ config/
β βββ api.js # API base URL configuration
βββ public/ # Static assets served as-is
β βββ videos/
β βββ background.mp4
βββ package.json # Dependencies and scripts
βββ vite.config.js # Vite configuration
βββ tailwind.config.cjs # Tailwind customization
Add a new page:
- Create file:
apps/web/src/pages/Contact.jsx - Add route in
App.jsx:<Route path="/contact" element={<Contact />} /> - Add navigation link:
<Link to="/contact">Contact</Link>
Create a reusable component:
// apps/web/src/components/Button.jsx
export default function Button({ children, onClick, variant = 'primary' }) {
const baseClasses = 'px-6 py-3 rounded-lg font-semibold transition-all';
const variantClasses = {
primary: 'bg-blue-600 hover:bg-blue-700 text-white',
secondary: 'bg-gray-200 hover:bg-gray-300 text-gray-800'
};
return (
<button
onClick={onClick}
className={`${baseClasses} ${variantClasses[variant]}`}
>
{children}
</button>
);
}- Status: β Complete
-
Location:
apps/backend/ -
Verification:
npm run devruns server at http://localhost:3000 -
Health Check: GET
/healthreturns 200 with status
-
Routes:
/api/menu(CRUD operations, supports category filtering) - Controllers: Business logic separated from routes
- Models: Data layer with mock/database functions
- Middleware: CORS, JSON parsing, logging
Express.js Request Flow:
Client Request
β
Express App (index.js)
β
Middleware (CORS, JSON parser, logger)
β
Routes (/api/menu β menuRoutes.js)
β
Controllers (menuController.js - business logic)
β
Models (menuModel.js - database/data access)
β
Response sent back to client
Why This Layered Architecture:
- Separation of Concerns: Each file has one responsibility
- Testability: Can test controllers without starting server
- Reusability: Models can be used by multiple controllers
- Maintainability: Changes in one layer don't affect others
Key Concepts:
Middleware Functions:
// Runs for every request
app.use((req, res, next) => {
console.log(`${req.method} ${req.url}`);
next(); // Pass to next middleware
});
// Runs only for specific routes
app.use('/api/menu', menuRoutes);RESTful API Design:
- GET
/api/menu- List all menu items - GET
/api/menu?category=Snack- List snack-category items - GET
/api/menu/:id- Get one menu item - POST
/api/menu- Create new menu item - PUT
/api/menu/:id- Update menu item - DELETE
/api/menu/:id- Delete menu item
apps/backend/
βββ index.js # Entry point, Express app setup
βββ src/
β βββ routes/ # URL routing definitions
β β βββ menuRoutes.js
β βββ controllers/ # Business logic
β β βββ menuController.js
β βββ models/ # Data access layer
β β βββ menuModel.js
β βββ utils/ # Helper functions
β βββ logger.js
βββ package.json # Dependencies and scripts
βββ Dockerfile # Container build instructions
Add a new API endpoint:
-
Create Model (
src/models/orderModel.js):
const orders = [];
exports.createOrder = (orderData) => {
const order = { id: Date.now(), ...orderData };
orders.push(order);
return order;
};
exports.getOrderById = (id) => {
return orders.find(o => o.id === parseInt(id));
};-
Create Controller (
src/controllers/orderController.js):
const orderModel = require('../models/orderModel');
exports.placeOrder = (req, res) => {
try {
const order = orderModel.createOrder(req.body);
res.status(201).json(order);
} catch (error) {
res.status(500).json({ error: error.message });
}
};-
Create Routes (
src/routes/orderRoutes.js):
const express = require('express');
const router = express.Router();
const orderController = require('../controllers/orderController');
router.post('/', orderController.placeOrder);
router.get('/:id', orderController.getOrder);
module.exports = router;- Register in index.js:
const orderRoutes = require('./src/routes/orderRoutes');
app.use('/api/orders', orderRoutes);-
Backend:
apps/backend/Dockerfile(development + production stages) -
Frontend:
apps/web/Dockerfile(development + build + production stages) -
Base Images: Using secure
node:lts-slimandnginx:stable-alpine-slim
-
Development:
docker-compose.yml- Hot reload, volume mounts -
Production:
docker-compose.prod.yml- Optimized builds, Nginx proxy - Services: PostgreSQL database, backend API, frontend UI
Why Docker for Development:
- Consistency: "Works on my machine" problem solved
- Isolation: Each service in its own container
-
Easy setup: New team members just run
docker compose up - Production parity: Dev environment matches production
Multi-Stage Build Benefits:
# Stage 1: Development (includes dev dependencies)
FROM node:lts-slim AS development
# ... install all dependencies
# Stage 2: Production (only production dependencies)
FROM node:lts-slim AS production
COPY --from=development /app/node_modules ./node_modules
# ... smaller, more secure imageWhy:
- Smaller final image (no dev dependencies)
- Faster deployment
- More secure (fewer packages = fewer vulnerabilities)
Docker Compose Service Dependencies:
services:
database:
# Starts first
backend:
depends_on:
database:
condition: service_healthy # Waits for DB health check
frontend:
depends_on:
- backend # Waits for backend to startImages vs Containers:
- Image: Read-only template (like a recipe)
- Container: Running instance of image (like a cooked dish)
- You can run multiple containers from one image
Volumes (Persistent Data):
volumes:
- postgres_data:/var/lib/postgresql/data # Database persists
- ./apps/backend:/app # Hot reload in developmentNetworks (Container Communication):
networks:
app-network: # Containers can use service names as hostnames
# backend can reach database at "postgres:5432"Environment Variables:
environment:
- NODE_ENV=development
- DATABASE_URL=postgres://user:pass@postgres:5432/db# Development workflow
docker compose up -d # Start all services (detached)
docker compose logs -f backend # Follow backend logs
docker compose restart backend # Restart one service
docker compose down # Stop all services
# Production workflow
docker compose -f docker-compose.prod.yml up --build -d
docker compose -f docker-compose.prod.yml ps
# Debugging
docker exec -it taste-of-aloha-backend sh # Enter backend container
docker logs taste-of-aloha-backend # View logs
docker inspect taste-of-aloha-backend # Detailed info
# Cleanup
docker compose down -v # Stop and remove volumes
docker system prune -a # Remove unused images/containersProblem: Port 3000 conflict when running both local dev server and Docker simultaneously
Why: You started npm run dev locally (uses port 3000), then tried docker compose up which also wants port 3000
Solution Options:
- Use only Docker for development:
# Stop local servers
# Ctrl+C in terminals running npm run dev
# Start Docker services
docker compose up -d
# Access:
# Frontend: http://localhost:5173
# Backend: http://localhost:3000- Use only local development:
# Stop Docker services
docker compose down
# Run local servers
cd apps/backend && npm run dev
cd apps/web && npm run dev-
Change Docker port mapping (in
docker-compose.yml):
backend:
ports:
- "3001:3000" # External:Internal- BrowserRouter: Wraps entire app for client-side routing
- Routes & Route: Define URL patterns and components
- Link: Navigation without page reload
- Pages: Home, Menu, About with proper routing
Client-Side Routing vs Server-Side:
Traditional (Server-Side):
User clicks link β Browser requests new page from server β
Server sends new HTML β Browser reloads page
React Router (Client-Side):
User clicks Link β JavaScript updates URL β
React Router renders new component β No page reload
Benefits:
- Faster navigation (no full page reload)
- Better user experience (smooth transitions)
- Less server load
- Preserves application state
Key Components:
// BrowserRouter: Uses HTML5 history API
<BrowserRouter>
{/* Your app */}
</BrowserRouter>
// Routes: Container for route definitions
<Routes>
<Route path="/" element={<Home />} />
<Route path="/menu" element={<Menu />} />
<Route path="/product/:id" element={<ProductDetail />} />
</Routes>
// Link: Navigation without reload
<Link to="/menu">Menu</Link>
// useNavigate: Programmatic navigation
const navigate = useNavigate();
navigate('/checkout');
// useParams: Access URL parameters
const { id } = useParams(); // From /product/:idProtected Routes (for authenticated users):
function ProtectedRoute({ children }) {
const isLoggedIn = /* check auth state */;
return isLoggedIn ? children : <Navigate to="/login" />;
}
<Route path="/admin" element={
<ProtectedRoute>
<AdminDashboard />
</ProtectedRoute>
} />Nested Routes:
<Route path="/dashboard" element={<DashboardLayout />}>
<Route index element={<DashboardHome />} />
<Route path="orders" element={<Orders />} />
<Route path="settings" element={<Settings />} />
</Route>URL Parameters & Query Strings:
// Route: /menu/:category?search=spicy
<Route path="/menu/:category" element={<Menu />} />
// In Menu component:
const { category } = useParams(); // 'appetizers'
const [searchParams] = useSearchParams();
const search = searchParams.get('search'); // 'spicy'-
Location:
Home.jsx - Video: Autoplay, loop, muted for browser compatibility
- Mobile Optimization: Detects screen width, shows static image on mobile
- Poster Image: Fallback while video loads
-
Tailwind Breakpoints: Mobile-first design with
md:andlg:prefixes - Mobile Detection: JavaScript-based with window resize listener
-
Typography: Scales from
text-5xltotext-7xlon larger screens
HTML5 Video Best Practices:
<video
autoPlay // Starts automatically
loop // Repeats indefinitely
muted // Required for autoplay in most browsers
playsInline // Prevents fullscreen on mobile Safari
poster="image.jpg" // Shows while loading
>
<source src="video.mp4" type="video/mp4" />
Your browser doesn't support video.
</video>Why these attributes:
-
autoPlay+muted: Browsers block unmuted autoplay (user experience policy) -
playsInline: iOS Safari forces fullscreen without this -
loop: Better than JavaScript for infinite loops -
poster: Improves perceived performance
Mobile-First Responsive Design:
// Tailwind breakpoints
sm: // >= 640px
md: // >= 768px
lg: // >= 1024px
xl: // >= 1280px
2xl: // >= 1536px
// Example
<h1 className="text-3xl md:text-5xl lg:text-7xl">
// Mobile: 3xl, Tablet: 5xl, Desktop: 7xl
</h1>JavaScript Media Queries:
const [isMobile, setIsMobile] = useState(
window.innerWidth < 768
);
useEffect(() => {
const handleResize = () => {
setIsMobile(window.innerWidth < 768);
};
window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
}, []);Video Optimization:
- Compress: Use tools like HandBrake to reduce file size
- Format: MP4 with H.264 codec for best compatibility
- Resolution: 1080p max for web, 720p for background videos
- Target: < 5MB for background videos
Image Optimization:
- WebP format: Better compression than JPEG
- Responsive images:
<img
srcSet="small.jpg 400w, medium.jpg 800w, large.jpg 1200w"
sizes="(max-width: 768px) 100vw, 50vw"
src="medium.jpg"
alt="Description"
/>Lazy Loading:
<img src="image.jpg" loading="lazy" alt="..." />
<video src="video.mp4" preload="none" />This is your primary learning objective moving forward. The order system will teach you full-stack development from database to UI.
Refer to BACKEND_API_GUIDE.md for API patterns, then follow this high-level order-system roadmap:
β‘ Create order model (OrderStatus enum, CRUD functions)
β‘ Create order controller (request handling, validation)
β‘ Create order routes (POST, GET endpoints)
β‘ Test with curl/Postman
β‘ Create Cart component (slide-out panel)
β‘ Implement cartSlice in Redux (add/remove/update)
β‘ Add "Add to Cart" buttons on Menu page
β‘ Display cart count in header
β‘ Create Checkout page (customer info form)
β‘ Implement delivery/pickup selection
β‘ Add form validation
β‘ Connect to order API
β‘ Create OrderConfirmation page
β‘ Display order details
β‘ Add order tracking functionality
β‘ Implement order status updates
Phase 1 - You'll Learn:
- How to structure API endpoints
- Data validation and error handling
- RESTful API design principles
- In-memory vs database storage
Phase 2 - You'll Learn:
- Redux state management (actions, reducers, selectors)
- Complex component interactions
- Shopping cart algorithms
- Local storage for persistence
Phase 3 - You'll Learn:
- Form handling in React
- Input validation strategies
- Conditional rendering (delivery vs pickup)
- API integration from frontend
Phase 4 - You'll Learn:
- Dynamic routing with parameters
- Real-time updates (optional: WebSockets)
- Order status flow
- User feedback patterns
1. Redux State Management:
// Think of Redux as a global state object
const globalState = {
cart: {
items: [...],
totalItems: 5,
subtotal: 29.99
},
orders: {
currentOrder: {...},
orderHistory: [...]
}
}
// Components can:
// - Read from this state (useSelector)
// - Modify this state (dispatch actions)2. Async Actions (API calls):
// Redux Toolkit's createAsyncThunk
const placeOrder = createAsyncThunk(
'orders/placeOrder',
async (orderData) => {
const response = await fetch('/api/orders', {
method: 'POST',
body: JSON.stringify(orderData)
});
return response.json();
}
);
// Handles loading/success/error states automatically3. Form Handling:
const [formData, setFormData] = useState({
name: '',
email: '',
address: ''
});
const handleChange = (e) => {
setFormData({
...formData,
[e.target.name]: e.target.value
});
};
const handleSubmit = (e) => {
e.preventDefault();
// Validate and submit
};React:
- React Docs - New official docs with interactive examples
- React Hooks Reference - Complete hook API
React Router:
- React Router Docs - Comprehensive routing guide
Redux Toolkit:
- Redux Toolkit Docs - Modern Redux patterns
- Redux Essentials Tutorial - Best starting point
Tailwind CSS:
- Tailwind Docs - Every utility class explained
- Tailwind UI Components - Pre-built component examples
Express.js:
- Express Guide - Routing and middleware
- Express API Reference - Complete API
Docker:
- Docker Get Started - Interactive tutorial
- Docker Compose - Multi-container apps
Full Stack Development:
Redux:
Docker:
VS Code Extensions:
- ES7+ React/Redux/React-Native snippets
- Tailwind CSS IntelliSense
- ESLint
- Prettier
- Docker (by Microsoft)
Browser Extensions:
- React Developer Tools
- Redux DevTools
API Testing:
- Postman - API testing tool
- Thunder Client - VS Code extension
- User Authentication: Login/signup with JWT tokens
- Admin Dashboard: Manage menu items, view orders
- Real-time Order Tracking: WebSocket integration
- Payment Integration: Stripe/PayPal checkout
- Email Notifications: SendGrid for order confirmations
1. Build in Small Increments:
- Don't try to implement everything at once
- Get one feature working completely before moving on
- Test frequently (every few changes)
2. Read Error Messages Carefully:
- Most errors tell you exactly what's wrong
- Google the error message if unclear
- Check line numbers and file names in stack traces
3. Use Console Logs Generously:
console.log('User data:', userData);
console.log('API response:', response);
console.log('Current state:', state);4. Understand Before Copying:
- Don't just copy code from Stack Overflow
- Read the explanation
- Modify it to fit your use case
5. Git Commits as Learning Log:
git commit -m "feat: add cart item quantity selector"
git commit -m "fix: resolve cart total calculation bug"
git commit -m "refactor: extract order form into component"6. Ask Questions:
- "Why does this work this way?"
- "What would happen if I changed this?"
- "Is there a better way to do this?"
-
β Verify all systems working:
# Terminal 1 cd apps/backend && npm run dev # Terminal 2 cd apps/web && npm run dev # Browser: http://localhost:5173
-
β Test Docker setup:
# Stop local servers first (Ctrl+C)
docker compose down docker compose up --build
3. π **Read BACKEND_API_GUIDE.md thoroughly**
- Understand the order flow
- Note the data structures
- Review example code
### This Week:
4. π¨ **Implement Phase 1: Backend Order API**
- Follow BACKEND_API_GUIDE.md patterns step by step
- Test each endpoint with curl or Postman
- Commit after each working feature
5. π **Study Redux Basics**
- Watch Redux Toolkit tutorial
- Understand actions, reducers, store
- Review existing `menuSlice.js` as example
### This Month:
6. π **Complete Full Order System**
- Phases 1-4 from the roadmap in this guide
- Working cart, checkout, confirmation
- All features tested and documented
7. π¨ **Polish UI/UX**
- Add loading spinners
- Improve error messages
- Mobile responsiveness testing
---
## β
Checklist: Are You Ready to Continue?
Before starting the order system, verify:
- [ ] You can run `npm run dev` in both backend and frontend
- [ ] Frontend shows at http://localhost:5173
- [ ] Backend health check returns 200: `curl http://localhost:3000/health | jq`
- [ ] You can navigate between Home, Menu, About pages
- [ ] You understand the difference between `apps/backend` and `apps/web`
- [ ] You've read through this entire learning guide
- [ ] You've scanned BACKEND_API_GUIDE.md
- [ ] Docker is running: `docker ps` shows no errors
**All checked?** You're ready to build the order system! π
**Some unchecked?** Review the relevant sections above and ask questions.
---
## π Getting Help
**When stuck, try this order:**
1. **Read the error message** - Most common cause of issues
2. **Check documentation** - Official docs are the best resource
3. **Search GitHub Issues** - Others likely had the same problem
4. **Ask specific questions** - Include error message, what you tried, expected vs actual behavior
**Good Question:**
> "I'm getting 'Cannot read property 'map' of undefined' on line 15 of Menu.jsx. The menu items array from Redux is undefined. I verified the API returns data. How do I debug Redux state?"
**Vague Question:**
> "My menu page doesn't work"
---
**Remember**: Every developer googles syntax, reads documentation, and debugs errors constantly. It's not about knowing everythingβit's about knowing how to figure things out! π
## Connectivity Verification Commands
Use the canonical connectivity checks in [QUICK_REFERENCE.md](../../QUICK_REFERENCE.md#connectivity-verification-powershell).