Phase 6Days 64-79

Databases — MongoDB + Postgres

Two real data layers: document (Mongoose) and relational (Drizzle + Postgres)

Phase Goal

Model and query real data in MongoDB, then put Postgres behind your Node API with Drizzle — schema as TypeScript, migrations, relations, transactions — and know exactly when to reach for each. You already know SQL; this teaches Drizzle from zero and how to spend that SQL knowledge inside a real backend.

Progress
Notes

Open the written lectures for this course before checking off the phase topics.

Mini Projects
Municipal Permit Index Benchmark
Festival Schedule Index Design
Clinic Waitlist Slow-Query Postmortem
Volunteer Registry Table, End to End
Equipment Booking Schema in Drizzle
Accessible Venue Feed, Two Query Styles
Seed-Exchange Ledger: Migrated and Transactional
Projects
Field Survey Archive on Mongo (in progress)
Field Survey + Collection APIs (checkpoint)
Mutual-Aid Inventory Lineage API — DEPLOYED

Day 64: Mongo Concepts & Atlas

Day 65: Mongoose Schemas & Models

Day 66: CRUD with Mongoose

Day 67: Relationships & Population

Day 68: Indexes from Scratch — How a Database Finds a Row

Mini Project
Municipal Permit Index Benchmark

Generate 300k synthetic permit applications with district, category, submittedAt, riskScore, and status; seed identical records into Postgres and Mongo. Measure equality, range, and sorted queries before/after indexing, report rows examined versus returned and wall time, and explain one case where ignoring the index is correct.

Day 69: Index Types & Index Design — Postgres and MongoDB

Mini Project
Festival Schedule Index Design

List six real festival-schedule queries: events by day, venue timetable, accessibility filter, performer lookup, text search, and upcoming changes. Break down equality/sort/range needs, design the smallest supporting index set, justify every index, and record one deliberately omitted index.

Day 70: Query Plans, Diagnosis & Index Maintenance

Mini Project
Clinic Waitlist Slow-Query Postmortem

Diagnose three slow clinic-waitlist reads: next patient per service, overdue triage cases, and clinician queue. Capture each plan, state a hypothesis, apply one fix, and compare examined/returned rows and wall time in Postgres and Mongo; leave one acceptable query unchanged and defend that choice.

Day 71: Aggregation Pipeline

Day 72: Mongo Transactions & Data Integrity

Day 73: Data-model Trade-off Workshop

Project
Field Survey Archive on Mongo (in progress)

Build a Mongo archive for field expeditions, sites, observations, specimens, and review notes with deliberate embedding/reference choices, supporting indexes, one aggregation, and one integrity-sensitive transaction. Finish and review it on Day 74.

Day 74: Query, Index & Migration Review

Project
Field Survey + Collection APIs (checkpoint)

Notes API + Blog backend, both on real Mongo Atlas, indexed, with an aggregation and a transaction. Next: give a relational database the same treatment.

Day 75: Postgres Behind Your API — Drizzle from Zero

Mini Project
Volunteer Registry Table, End to End

Add a real Postgres volunteer registry to the Phase 5 Express service with Drizzle: schema, configuration, migration, db singleton, and validated create/list endpoints. Print the generated SQL and explain the uniqueness, status, and availability constraints.

Day 76: Modeling a Real Schema — Types, Constraints & Indexes

Mini Project
Equipment Booking Schema in Drizzle

Model equipment, locations, borrowers, bookings, bookingItems, and maintenance holds relationally. Include an enum status, non-overlap/inventory constraints you can defend, explicit cascade rules, and indexes for availability and history. Derive insert types and Zod schemas from tables.

Day 77: Querying with Drizzle — Builder & Relational Queries

Mini Project
Accessible Venue Feed, Two Query Styles

Build an accessible-venue feed twice against a venue/access-feature/inspection schema: once with relational queries and once with explicit joins plus reshape. Inspect SQL and plans, choose one implementation with evidence, then replace offset pagination with a stable `(verifiedAt, id)` cursor.

Day 78: Migrations, Seeding & Transactions

Mini Project
Seed-Exchange Ledger: Migrated and Transactional

Create versioned migrations for seed varieties, members, offers, and exchanges; add a column through expand/backfill/contract and write an idempotent seed. Complete an exchange plus inventory decrement transactionally, prove rollback by throwing halfway, and map a duplicate offer key to 409.

Day 79: Project — Mutual-Aid Inventory Lineage API

Capstone
Mutual-Aid Inventory Lineage API — DEPLOYED

Build a Postgres/Drizzle API that traces donated goods from intake batch through storage, reservation, handoff, and adjustment. Support full-text search, faceted filters, and cursor pagination; make every multi-record handoff transactional, enforce invariants in the database, seed realistic batch histories, test against a real database, and defend the relational model.

  • Claims link to sources and tags through explicit join tables; every response preserves provenance.
  • Search, faceted filters, keyset pagination, deliberate indexes, and an EXPLAIN ANALYZE plan you can explain.
  • Versioned Drizzle migrations, an idempotent seed script, and integration tests against a real Postgres.
  • One transactional ingest that is provably all-or-nothing, and constraint violations mapped to correct HTTP status codes.

Phase Complete!

After this phase, you'll be able to:

  • Mongo + Mongoose: schema, queries, indexes, aggregation, transactions
  • Population & N+1 avoidance (in Mongoose and any ORM)
  • Reading explain() output
  • Put Postgres behind a Node API with Drizzle: schema as TypeScript, constraints, indexes, inferred types
  • Query with both the builder and relational queries; read the SQL Drizzle compiles and tune it
  • Versioned migrations, safe zero-downtime schema changes, seeding, and ACID transactions
  • Choose document vs relational deliberately (and say where a typed query builder beats a raw driver)

Your APIs persist real data in both a document and a relational store. Now make them know who's asking.