79 lines
4.3 KiB
Markdown
79 lines
4.3 KiB
Markdown
%{
|
|
title: "Scheduled Publishing & Author Dashboard",
|
|
author: "Willem van den Ende",
|
|
tags: ~w(release features),
|
|
description: "Future-dated posts stay hidden until their publish date, authors get a dashboard to track drafts and scheduled content, and registration is locked down to invited emails only."
|
|
}
|
|
---
|
|
|
|
This post was generated by a coding agent, after using the demo skill to make a demo using Rodney and Showboat (thanks Simon Willison). I find it fun and useful to see this, gives some indication of what went in.
|
|
|
|
There is a note at the bottom about tools used and the number of phases.
|
|
|
|
# As the agent wrote:
|
|
|
|
Posts in Firehose are markdown files with a date in the filename. Until now, every published post was immediately visible. That changes today: posts with a future date are now hidden from public views until their date arrives.
|
|
|
|
This was built in a single session using an agentic dev team -- 12 issues tracked in beads, executed in three parallel phases, producing 232 tests across the blogex library and Phoenix app.
|
|
|
|
## What changed
|
|
|
|
### Future-dated posts are hidden from public views
|
|
|
|
The blog index, tag pages, RSS feeds, and Atom feeds now filter out posts where the date is after today. If you schedule a post for next Tuesday, readers won't see it until then.
|
|
|
|

|
|
|
|
But here's the key design choice: **direct URL access still works**. If you know the slug, you can view the post. This lets authors share preview links with reviewers before the publish date.
|
|
|
|

|
|
|
|
### Status banners for authors
|
|
|
|
When you're logged in, draft and scheduled posts show a status banner so you always know what state a post is in. Unauthenticated visitors see nothing -- no clue the post isn't "live" yet.
|
|
|
|
**Scheduled posts** show a blue banner with the target date:
|
|
|
|

|
|
|
|
**Draft posts** (unpublished) show an amber banner:
|
|
|
|

|
|
|
|
### Editor dashboard
|
|
|
|
A new LiveView at `/editor/dashboard` gives authors a unified view of all non-live content across every blog. Two tabs: drafts and scheduled posts. Scheduled posts show a "days until live" countdown.
|
|
|
|

|
|
|
|

|
|
|
|
The dashboard requires authentication -- unauthenticated users are redirected to the login page.
|
|
|
|
### Authentication and registration gating
|
|
|
|
We added `mix phx.gen.auth` for session-based authentication with magic links and password login. Login and registration pages are accessible by direct URL only -- they're intentionally not linked from the public navigation.
|
|
|
|
Registration is gated to a single email via the `ALLOWED_REGISTRATION_EMAIL` environment variable. Anyone else gets a polite rejection:
|
|
|
|

|
|
|
|
When the environment variable isn't set, registration is disabled entirely. A demo user (`demo@example.com`) is seeded in dev for local testing.
|
|
|
|
## How it was built
|
|
|
|
The feature was planned as an [Allium specification](https://github.com/your-org/allium) with surfaces, rules, and domain entities, then broken into 12 beads (issues) across three phases:
|
|
|
|
1. **Scheduled posts** (5 beads): date filtering in blogex, unfiltered direct access, feed/router verification
|
|
2. **Authentication** (3 beads): phx.gen.auth scaffolding, registration gating, dev seed
|
|
3. **Dashboard** (4 beads): post visibility helpers, unfiltered registry access, LiveView dashboard, status banners
|
|
|
|
All 12 beads were executed with parallel agentic workers in isolated git worktrees, then merged and integrated on main. The demo caught one bug (auth check using `current_user` instead of `current_scope`) which was fixed before this post.
|
|
|
|
## By the numbers
|
|
|
|
- **232 tests** passing (89 blogex + 143 Phoenix app)
|
|
- **12 beads** planned, executed, and closed
|
|
- **3 phases** run with parallel workers
|
|
- **0 compiler warnings**
|