{"slug": "one-folder-shape-for-every-course-a-lifecycle-monorepo-convention", "title": "One folder shape for every course: a lifecycle monorepo convention", "summary": "A developer created a lifecycle monorepo convention for course material, organizing each course into five numbered stages from planning to post-training. The system includes a copy-to-start template with angle-bracket slots that must be filled, and a grep command that returns nothing when the course is complete. The convention also features an archived folder for retired decisions and a CLAUDE.md file to make the structure machine-readable.", "body_md": "`00-planning → 04-post-training`\n\n.`_TEMPLATE/`\n\nyou copy to start the next one, an `_ARCHIVED/`\n\nyou park old stuff in, and a `CLAUDE.md`\n\nthat makes the convention machine-readable.`<angle-bracket-slots>`\n\n, and \"done\" is a `grep`\n\nthat returns nothing.I had course material scattered across repos — planning notes here, marketing copy there, facilitator run-sheets in a third place. Every new course started from a blank page, and I re-invented the folder layout each time. So I collapsed everything into one monorepo with a single rule: **every course has the identical shape.**\n\nThe insight isn't \"use folders\" — it's that a course has a *lifecycle*, and numbered folders make that lifecycle the primary axis instead of file type. Plan it, sell it, teach it, run it, follow up. Five stages, always in order:\n\n| Folder | Stage | What lives here |\n|---|---|---|\n`00-planning/` |\nPrepare | Syllabus (source of truth), specs |\n`01-marketing/` |\nSell | Positioning master + channel assets |\n`02-content/` |\nTeach | Modules, one file each |\n`03-delivery/` |\nRun | Run-sheet, pre-flight checklist, fallback plan |\n`04-post-training/` |\nFollow up | Feedback form, follow-up email, post-mortem |\n\nThe numeric prefix isn't decoration. It forces sort order to match the actual workflow, so the folder listing reads like the process itself. Same reason migration files are timestamped — order is information.\n\n``` php\n<course>/\n  00-planning/       -> derives everything below\n  01-marketing/\n  02-content/\n  03-delivery/\n  04-post-training/  --. post-mortem findings\n                        |\n     ^------------------'  feed back into 00..03\n```\n\nThat loop at the end matters: the post-mortem doesn't sit in a graveyard folder. Its findings flow back into the syllabus, the run-sheet, the marketing. The structure runs the same feedback loop it's supposed to teach.\n\n`_TEMPLATE/`\n\n: a course starts as a copy\nStarting a new course is one line:\n\n```\ncp -r _TEMPLATE my-new-course\n```\n\nThe template is the full lifecycle skeleton with the writing already stubbed. What you must fill is marked as `<angle-bracket-slots>`\n\n— `<course-name>`\n\n, `<promise-one-liner>`\n\n, and so on. Everything *not* in a slot is standing structure you keep.\n\nThe part I like most is the definition of done. A course is ready when this returns nothing:\n\n```\ngrep -rn '<' --include='*.md' .\n```\n\nNo slot hits = no unfilled blanks. It turns \"is this finished?\" from a judgment call into a command with an exit code — the same instinct as a failing test. If I were wiring this into CI, that grep becomes the assertion.\n\n`_ARCHIVED/`\n\n: park it, don't delete it\nRetired formats and old campaigns go into `_ARCHIVED/`\n\n, in dated subfolders with a note on *why* it was retired and what replaced it. One rule keeps it honest: **nothing live may reference anything in there.** If a live file still links to it, it isn't archived — it's just moved.\n\nWhy keep it at all? Because a retired price, a killed campaign style, or an abandoned format is a *recorded decision*. Deleting it loses the \"we already tried that, here's why it didn't work.\" Git history technically has it, but nobody spelunks reflog for a pricing decision.\n\n`CLAUDE.md`\n\n: the convention, machine-readable\nThe last piece is a `CLAUDE.md`\n\nat the root that spells out the layout, the naming rules, and the standing decisions. It's written for an AI coding agent, but the real value is broader: it's the one file where the convention lives as text instead of as tribal knowledge in my head. Any collaborator — human or agent — reads one file and knows where things go.\n\nThe pattern generalizes past courses. Any repeatable body of work with a lifecycle — client engagements, product launches, incident write-ups — benefits from the same three moves: **one fixed shape, a copy-to-start template with a grep-checkable done state, and a parking lot for retired decisions.** Consistency you can `grep`\n\nbeats consistency you have to remember.", "url": "https://wpnews.pro/news/one-folder-shape-for-every-course-a-lifecycle-monorepo-convention", "canonical_source": "https://dev.to/nasrulhazim/one-folder-shape-for-every-course-a-lifecycle-monorepo-convention-383f", "published_at": "2026-07-22 15:46:35+00:00", "updated_at": "2026-07-22 16:00:53.010393+00:00", "lang": "en", "topics": ["developer-tools"], "entities": [], "alternates": {"html": "https://wpnews.pro/news/one-folder-shape-for-every-course-a-lifecycle-monorepo-convention", "markdown": "https://wpnews.pro/news/one-folder-shape-for-every-course-a-lifecycle-monorepo-convention.md", "text": "https://wpnews.pro/news/one-folder-shape-for-every-course-a-lifecycle-monorepo-convention.txt", "jsonld": "https://wpnews.pro/news/one-folder-shape-for-every-course-a-lifecycle-monorepo-convention.jsonld"}}