The Finish Line — What's Fake and Why
Okay so — the dashboard is lying to you
Real talk: this dashboard looks finished, and that's the trap. The clock, the focus timer, the "now playing" bar, the streak counter, the weekly metric bars, the task checkboxes — they all look alive. Most of them are painted on. The FOCUS time says "2h 14m" because someone typed "2h 14m" into a PHP array. The practice grid shows minutes because there's a literal list of numbers in index.php. Tick a task checkbox and refresh — it forgets. It's a movie set: gorgeous from the front, two-by-fours holding up a flat facade from the back.
That's not a criticism, by the way. Building the facade first is a totally legit way to design — you nail the vibe, then make it real. That "make it real" part is this entire module. We're going to walk around to the back of the set and turn the painted windows into working ones, one at a time.
The honest audit
Here's what's actually real right now, before we touch anything:
- The tutorial content + "mark chapter done." The progress toggle genuinely works — it just stores progress in the session (more on why that's fragile in a second).
- The live clock, focus timer, and music player. These got wired up in the next two chapters' worth of work — if your clock is ticking and the timer counts down, that part's done. If it's frozen, you haven't done chapters 02–03 yet.
And here's what's still painted on:
- Home stats — FOCUS, STREAK, MOON, WEATHER, the weekly metric bars, the activity log, today's queue. All hardcoded arrays.
- Work tasks + focus log — the checkboxes don't persist, the log is a fixed list.
- Music practice grid + playlist — the 14-day grid is a literal array of minutes; the playlist doesn't remember anything.
- Login — there isn't one. Anyone who can reach the page sees everything.
- Editing — there's no way to add a task, edit the playlist, or change any content without opening
index.phpin an editor.
Why it's all fake — two root causes
Almost every fake thing traces back to one of two missing pieces, and naming them makes the whole module click into place.
Cause one: there's no database. The site has nowhere to remember anything. Progress is shoved into $_SESSION, which is per-browser and evaporates the moment a cookie gets cleared (the comment at the top of progress.php literally admits this and says "switch to a file or DB later" — that "later" is chapter 4). Everything else just hardcodes its data because there's no shelf to put real data on. A database is the shelf. It's the single most important thing we add, which is why it sits early in the order and half the later chapters depend on it.
Cause two: there was no JavaScript. The site was built "no-JS by design" — navigation is all query strings, rendering is all server-side. That's a genuinely nice, sturdy approach, and we're going to keep it for everything that can stay server-rendered. But a clock that ticks every second, a countdown timer, and an audio player physically cannot work without a little client-side code. So we add a thin JavaScript layer — only where it's unavoidable. That's called progressive enhancement, and chapter 2 is where we introduce it.
🐍 Python brain: think of the database as the difference between a script that prints hardcoded values and one that actually reads from sqlite3 / a real DB. Same energy. Right now the dashboard is the print("STREAK: 11 days") version. We're upgrading it to print(f"STREAK: {compute_streak()} days").
The dependency map (this is the important bit)
You asked to sort these by difficulty and respect dependencies, and those two goals happen to point the same direction. Here's the logic:
- The clock and timer and audio player depend on nothing but a browser. They're the easy, instant-gratification wins, so they go first.
- The database depends only on what Parts 1–2 already taught you (MariaDB + PDO). It's the lynchpin: tasks, stats, practice logging, login, and editing all sit on top of it. So it goes right after the freebies.
- Tasks, stats, and practice each just need the database, so they come next.
- Login needs the database (a users table).
- Editing needs the database and login (you must know who someone is before you let them delete things). So it's last among the real features.
- Polish ties a bow on all of it.
The build order + difficulty legend
So here's the whole module at a glance. EASY = an afternoon. MEDIUM = a focused day. HARD = take your time, it's security-sensitive.
- 02 · timer — EASY — live clock + focus timer (already wired; this chapter explains it)
- 03 · player — EASY → MEDIUM — real audio playback (already wired; explained here)
- 04 · database — MEDIUM — the lynchpin: PDO helper, schema, persistent progress
- 05 · tasks — MEDIUM — real add/check/delete tasks (needs 04)
- 06 · stats — MEDIUM — kill the fake Home numbers (needs 04, 05)
- 07 · practice — MEDIUM — real practice logging + playlist (needs 03, 04)
- 08 · auth — HARD — multi-user login (needs 04)
- 09 · editing — HARD — admin CRUD / edit mode (needs 04, 08)
- 10 · polish — MEDIUM — flash messages, backups, security, what's next
Notice chapters 2 and 3 are already done if your clock is ticking — they document live code that's wired into index.php and app.js right now. From chapter 4 onward, you're building genuinely new stuff.
▣ Mini Project: Tidy the Workshop
Before any real building, let's clear the bench. Every project accumulates a little junk, and this one has a couple of stray files plus a useful tool nobody can reach. Cleaning up now means that when we're knee-deep in the database chapter, we're not tripping over mystery files wondering if they matter. It's the coding equivalent of doing the dishes before you cook.
- Open the project folder and find
own-banner.php. Crack it open — it contains literally one line: its own filename. It's a stray from an old exercise. Delete it:rm own-banner.php(or just delete it in your editor). - Now find
banner.php— that one's a real, working tool (a "Type Inspector" that shows how PHP casts a value). It works great but nothing links to it. We'll give it a home later in the editing chapter; for now just visit it directly atbanner.php?v=0and confirm it still runs, so you know it's worth keeping. - Open
index.phpand scroll through thehome,music, andworksections. Every place you see a PHP$array = [...]of display data (the activity log, the metric bars, the queue, the practice minutes, the tasks), drop a quick// FAKE: replace in ch0Xcomment above it. You're literally annotating the movie set. - Count them. That number is your scoreboard — every fake array you replace in the coming chapters, delete its comment. The module is done when there are no
// FAKEcomments left.
Stretch goals:
- Add the project to git if it isn't already, and make a commit called "ch1: audit + cleanup" so you have a clean restore point before the real work.
- Sketch the dependency map on paper. Seriously — drawing the arrows yourself makes the build order stick.
What you flexed: reading a codebase critically, separating real from fake, identifying root causes (no DB, no JS) instead of treating symptoms, and ordering work by dependency. That's the senior-dev skill nobody teaches in syntax tutorials — knowing what to build and in what order, before writing a line of it.