🚀 DECEMBER DAY 1: 312 Developers. 31 Days. Let's Ship.
No more theory. No more planning. Today we build.
Your Day 1 Mission (Complete in 1 Hour):
Step 1: Database (10 minutes)
Step 2: Project Structure (10 minutes)
Step 3: First Endpoint (20 minutes)
Step 4: Test & Commit (10 minutes)
🏆 Day 1 Leaderboard (Live):
First to commit: @alex_dev (00:03 UTC!)
Most tables created: @maria_builds (8 tables)
Already deployed: @tom_ships (on Railway!)
Best project name: @sara_codes ("DecemberOrDie")
Current Status:
156 databases created
89 first commits pushed
12 already deployed
3 have users table with data
💬 Day 1 Check-in:
Comment with:
✅ Database created
✅ First endpoint working
✅ Git commit hash
🎯 Tomorrow's goal
🔥 Day 1 Wisdom:
"Line 1 is harder than lines 2-1000. You just wrote line 1."
"A working database with one table beats a perfect plan with zero tables."
"Day 1 is 90% of the battle. You're here. You started."
Tomorrow (Day 2):
Add authentication
Create your core table
Deploy somewhere
Remember: You don't need perfect. You need progress.
Who shipped something today? Drop your commit hash! 🚀
#December #Day1 #PostgreSQL #Shipping #Building
@postgres
No more theory. No more planning. Today we build.
Your Day 1 Mission (Complete in 1 Hour):
Step 1: Database (10 minutes)
-- Create your December database
CREATE DATABASE december_project;
\c december_project;
-- Your first table (modify for your project)
CREATE TABLE users (
id SERIAL PRIMARY KEY,
email VARCHAR(255) UNIQUE NOT NULL,
name VARCHAR(255),
created_at TIMESTAMP DEFAULT NOW()
);
-- Verify it works
INSERT INTO users (email, name) VALUES ('[email protected]', 'Day 1');
SELECT * FROM users;
-- See that row? You're shipping!
Step 2: Project Structure (10 minutes)
mkdir my-december-project
cd my-december-project
npm init -y
npm install express pg dotenv
# Create structure
touch server.js .env README.md
echo "DATABASE_URL=postgresql://localhost/december_project" > .env
echo "# Shipping December 2024 🚀" > README.md
Step 3: First Endpoint (20 minutes)
// server.js - Your first working code
const express = require('express');
const { Pool } = require('pg');
require('dotenv').config();
const app = express();
const pool = new Pool({ connectionString: process.env.DATABASE_URL });
app.use(express.json());
app.get('/', (req, res) => {
res.json({ message: 'December Project - Day 1', status: 'shipping' });
});
app.get('/api/users', async (req, res) => {
const result = await pool.query('SELECT * FROM users');
res.json(result.rows);
});
app.post('/api/users', async (req, res) => {
const { email, name } = req.body;
const result = await pool.query(
'INSERT INTO users (email, name) VALUES ($1, $2) RETURNING *',
[email, name]
);
res.json(result.rows[0]);
});
const PORT = 3000;
app.listen(PORT, () => {
console.log(`December Project running on port ${PORT}`);
});
Step 4: Test & Commit (10 minutes)
# Run it
node server.js
# Test it (new terminal)
curl localhost:3000
curl localhost:3000/api/users
# Commit it
git init
git add .
git commit -m "Day 1: Database + API working"
# Share your commit hash below!
🏆 Day 1 Leaderboard (Live):
First to commit: @alex_dev (00:03 UTC!)
Most tables created: @maria_builds (8 tables)
Already deployed: @tom_ships (on Railway!)
Best project name: @sara_codes ("DecemberOrDie")
Current Status:
156 databases created
89 first commits pushed
12 already deployed
3 have users table with data
💬 Day 1 Check-in:
Comment with:
✅ Database created
✅ First endpoint working
✅ Git commit hash
🎯 Tomorrow's goal
🔥 Day 1 Wisdom:
"Line 1 is harder than lines 2-1000. You just wrote line 1."
"A working database with one table beats a perfect plan with zero tables."
"Day 1 is 90% of the battle. You're here. You started."
Tomorrow (Day 2):
Add authentication
Create your core table
Deploy somewhere
Remember: You don't need perfect. You need progress.
Who shipped something today? Drop your commit hash! 🚀
#December #Day1 #PostgreSQL #Shipping #Building
@postgres
❤4
🔐 DECEMBER DAY 2: Add Auth in 30 Minutes
Yesterday: Database ✅
Today: Authentication
Tomorrow: Your core feature
Pick Your Auth Method:
Option 1: Password Auth (Classic)
Option 2: Magic Links (No Passwords!)
Protect Your Routes:
🎯 Day 2 Success = 3 Things Work:
✅ Can register/login
✅ Get a token back
✅ Token protects routes
📊 Day 2 Live Stats:
Password auth: 67 devs
Magic links: 23 devs
Still building: 12 devs
Quick Test:
Day 2 Check-in:
✅ Auth working?
🔐 Which method?
⏱️ Time taken?
Tomorrow: Build your ONE core feature
Pro tip: Don't overthink. Basic auth shipped > Perfect auth planned.
Who has auth working? 🔐
#December #Day2 #Auth #Building
@postgres
Yesterday: Database ✅
Today: Authentication
Tomorrow: Your core feature
Pick Your Auth Method:
Option 1: Password Auth (Classic)
npm install bcrypt jsonwebtoken
// Register
app.post('/api/register', async (req, res) => {
const { email, password } = req.body;
const hashedPassword = await bcrypt.hash(password, 10);
const result = await pool.query(
'INSERT INTO users (email, password_hash) VALUES ($1, $2) RETURNING id, email',
[email, hashedPassword]
);
const token = jwt.sign(
{ userId: result.rows[0].id },
process.env.JWT_SECRET || 'december-2024',
{ expiresIn: '7d' }
);
res.json({ user: result.rows[0], token });
});
// Login
app.post('/api/login', async (req, res) => {
const { email, password } = req.body;
const user = await pool.query('SELECT * FROM users WHERE email = $1', [email]);
if (!user.rows[0]) return res.status(401).json({ error: 'Invalid credentials' });
const validPassword = await bcrypt.compare(password, user.rows[0].password_hash);
if (!validPassword) return res.status(401).json({ error: 'Invalid credentials' });
const token = jwt.sign(
{ userId: user.rows[0].id },
process.env.JWT_SECRET || 'december-2024',
{ expiresIn: '7d' }
);
res.json({ token });
});
Option 2: Magic Links (No Passwords!)
// Send magic link
app.post('/api/magic', async (req, res) => {
const token = crypto.randomBytes(32).toString('hex');
await pool.query(
`INSERT INTO magic_tokens (email, token, expires_at)
VALUES ($1, $2, NOW() + INTERVAL '15 minutes')`,
[req.body.email, token]
);
console.log(`Magic link: https://localhost:3000/magic/${token}`);
res.json({ message: 'Check console for magic link' });
});
// Verify magic link
app.get('/magic/:token', async (req, res) => {
const result = await pool.query(
'SELECT email FROM magic_tokens WHERE token = $1 AND expires_at > NOW()',
[req.params.token]
);
if (!result.rows[0]) return res.status(401).json({ error: 'Invalid token' });
// Create/get user and return JWT
const token = jwt.sign({ email: result.rows[0].email }, 'december-2024');
res.json({ token });
});
Protect Your Routes:
const authenticate = (req, res, next) => {
const token = req.headers.authorization?.split(' ')[1];
if (!token) return res.status(401).json({ error: 'No token' });
try {
req.user = jwt.verify(token, process.env.JWT_SECRET || 'december-2024');
next();
} catch {
res.status(401).json({ error: 'Invalid token' });
}
};
// Use it
app.get('/api/me', authenticate, (req, res) => {
res.json({ userId: req.user.userId });
});
🎯 Day 2 Success = 3 Things Work:
✅ Can register/login
✅ Get a token back
✅ Token protects routes
📊 Day 2 Live Stats:
Password auth: 67 devs
Magic links: 23 devs
Still building: 12 devs
Quick Test:
# Register
curl -X POST localhost:3000/api/register \
-H "Content-Type: application/json" \
-d '{"email":"[email protected]","password":"test123"}'
Day 2 Check-in:
✅ Auth working?
🔐 Which method?
⏱️ Time taken?
Tomorrow: Build your ONE core feature
Pro tip: Don't overthink. Basic auth shipped > Perfect auth planned.
Who has auth working? 🔐
#December #Day2 #Auth #Building
@postgres
❤2🔥2