For Product Managers & Designers who want to ship β not just prompt
What changed β and why it matters to you
Speed without structure = tech debt on a credit card
npm install flask-auth-helper β a package that doesn't exist. An attacker published a malicious package with that exact name. Supply chain attack.
Engineering literacy is the immune system that prevents this.
You don't need to be an engineer. You need to think like one.
Plus: Cloud & Deployment as a capstone skill
Your engineering constitution for AI teammates
Write your engineering standards ONCE, AI follows them EVERY time.
| File | Tool |
|---|---|
.github/copilot-instructions.md | GitHub Copilot |
CLAUDE.md | Claude Code |
.cursorrules | Cursor |
AGENTS.md | VS Code agents |
## Role
You are a senior engineering partner. I am a PM learning to code.
Explain what you're doing and why. Teach as you go.
## Code Style
- Descriptive names (getUserById, not doStuff)
- One function does one thing
- Prefer readability over cleverness
## Security
- NEVER hardcode secrets β use .env
- Validate all user input
- Use parameterized queries
## Testing
- Write tests alongside code
- Test happy path AND edge cases
## Git
- Meaningful commits: feat(auth): add login form
- Never commit .env or node_modules
π‘ Add framework-specific overrides too β React patterns, iOS conventions, Python style sections.
The command line is your cockpit, not a scary relic
# Navigate
pwd # Where am I?
ls -la # What's here? (with details)
cd my-project # Go into a folder
cd .. # Go up one level
# Read files
cat README.md # Print file contents
head -20 server.js # First 20 lines
grep "error" log.txt # Find "error" in a file
# Chain commands with pipes
cat log.txt | grep "ERROR" | wc -l # Count errors
# Permissions & packages
chmod +x script.sh # Make it runnable
npm install # Install JS dependencies
brew install git # Install git (macOS)
$ npm start
Error: Cannot find module 'express'
at Module._resolveFilename (node:internal/modules/cjs/loader:1075:15)
at Module._load (node:internal/modules/cjs/loader:920:27)
Cannot find module 'express'npm install expressThink before you prompt
No plan
"Build me a todo app"
β 500 lines in one file
β No structure
β Can't add features
β Start over
With a plan
"Here's my file structure:
/src
/components
/api
/utils
Build the TodoList component"
β Clean, modular, extendable
my-app/
βββ src/
β βββ components/ # UI pieces (buttons, forms)
β βββ pages/ # Full screens
β βββ api/ # Backend calls
β βββ utils/ # Helper functions
β βββ styles/ # CSS / design tokens
βββ tests/ # Test files
βββ public/ # Static assets
βββ .env # Secrets (NEVER commit)
βββ .gitignore # What git should ignore
βββ package.json # Dependencies
βββ README.md # What is this & how to run it
getUserById not doStuffYour code's save game system
# Start tracking a project
git init
git add .
git commit -m "Initial commit: project setup"
# Daily workflow
git add .
git commit -m "Add user login form"
git push origin main
# Branching (safe experimentation)
git checkout -b feature/dark-mode
# ... make changes ...
git commit -m "Add dark mode toggle"
git push origin feature/dark-mode
# Then: open a Pull Request on GitHub
Commit messages
Add password reset email flow
Fix: cart total not updating on remove
update stuff
asdfasdf
fix
.gitignore (never commit these)
node_modules/
.env
.DS_Store
dist/
*.log
β οΈ Once a secret is committed, it's in the history forever β even if you delete it
Read the error. Then ask AI for help.
Repeat until you have 47 open tabs and no idea what's happening
console.log("user data:", user); // What is this actually?
console.log("reached step 3"); // Did we get here?
Your safety net against AI hallucinations
Start with unit tests. They're fast, easy, and catch the most bugs per effort.
Tell AI to write tests first, then the code:
Prompt: "Write unit tests for a function called
calculateDiscount(price, couponCode) that:
- Returns 10% off for code 'SAVE10'
- Returns 0 for invalid codes
- Throws an error for negative prices
Then implement the function to pass these tests."
Trust, but verify
Level 1: Code Review
Level 2: AI Product Evaluation
Both matter. Level 1 is where you start. Level 2 is where you grow.
Before accepting any AI-generated code, ask:
pip install super-easy-auth β Google it. Does it exist?magicLibrary.doEverything()// This securely hashes the password β¦ it doesn't| Dimension | 1 (Poor) | 3 (Acceptable) | 5 (Excellent) |
|---|---|---|---|
| Accuracy | Factually wrong | Mostly correct, minor errors | Fully accurate, verified |
| Relevance | Off-topic | Addresses the question | Directly answers with context |
| Safety | Harmful content | No harm but no guardrails | Safe with disclaimers |
| Tone | Wrong brand voice | Neutral | Matches brand perfectly |
Rubrics turn "does it feel right?" into measurable scores.
π€ Human Eval
π€ LLM-as-Judge
π Programmatic
Tools: Braintrust, Promptfoo, LangSmith, OpenAI Evals
Don't ship what you don't understand
' OR 1=1 -- and downloads your entire database.
# .env (add to .gitignore!)
DATABASE_URL=postgres://user:pass@host/db
STRIPE_KEY=sk_live_abc123
When generating code, ALWAYS:
- Use environment variables for secrets (never hardcode)
- Add authentication checks to all API routes
- Sanitize and validate all user input
- Use parameterized queries (never string concatenation)
- Add rate limiting to public endpoints
- Set CORS headers appropriately
If it's not automated, it's broken
CI β Continuous Integration
CD β Continuous Deployment
# .github/workflows/ci.yml
name: CI
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
- run: npm install
- run: npm test
That's it. Every push now runs your tests automatically. If they fail, you know before deploying.
| Approach | How it works | Example |
|---|---|---|
| Platform auto-deploy | Connect GitHub β push = deploy | Vercel, Netlify, Railway |
| Actions β Platform | Actions runs deploy command | AWS, Azure, custom servers |
| GitHub Pages | Actions builds β pushes to gh-pages | Static sites, docs |
name: CI/CD
on:
push:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
- run: npm install
- run: npm test
deploy:
needs: test
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
- run: npm run build
- uses: peaceiris/actions-gh-pages@v4
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./dist
needs: test β deploy ONLY runs if tests passif: github.ref == 'refs/heads/main' β only deploy from main branch, not feature branchesPackage and ship your vibe-coded project
# Dockerfile
FROM node:20-slim
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD ["npm", "start"]
# Build and run
docker build -t my-app .
docker run -p 3000:3000 my-app
| Platform | Best For | Difficulty |
|---|---|---|
| Vercel | Frontend, Next.js | β Easy |
| Railway | Full-stack, databases | β Easy |
| Render | APIs, web services | ββ Medium |
| AWS / Azure / GCP | Enterprise, scale | βββ Hard |
Start with Vercel or Railway. Graduate to AWS/Azure when you need to.
You're the architect. AI is the builder.
Before AI
With AI
All four layers = you can ship products independently
Concrete steps to build these skills
ls, cd, pwd. Navigate around.Free Courses
Tools to Try
Without engineering literacy:
π Γ π€ = πππ
With engineering literacy:
π§ Γ π€ = πππ
Start this week. Open a terminal. Init a repo. Build something.
π οΈ The future belongs to builders.