Publication Feature — Minimum Viable Product
Publication Feature — Minimum Viable Product
Core domain model
- Accounts (users) own publications.
- Publications own posts.
- Renamed from "Site/Project"
- Posts are not directly associated with accounts.
Accounts are administrative only; publications are the primary public-facing entity.
URL spaces
Publication space (public, active)
- Publications live at the root URL namespace:
/publication-slug/→ publication index (list of posts)/publication-slug/post-slug→ post
- No
/p/,/posts/, or nested user paths. - Clean, GitHub-like URLs.
User space (reserved, inactive for MVP)
- User/account URLs are conceptually separated and live under:
/@username - For MVP: will have basic userspace or may not exist publicly at all. (for MVP just leave in fact)
- It is reserved for future use (author pages, profiles, etc.).
Signup and onboarding (MVP)
- No forced publication creation on signup.
- After signup, users land on a user/account dashboard.
- Users may create a publication when they choose.
This avoids premature editorial decisions and keeps onboarding minimal.
Create publication flow (required for MVP)
From the user dashboard:
- User selects Create publication.
- Creation flow:
- Publication slug:
- Defaults to the user’s username.
- Fully editable.
- Explicit message: “You can change this later.”
- Optional publication display name.
- Publication slug:
- Publication is created.
- User is redirected to the publication dashboard.
This same flow can later be reused for additional publications.
Dashboards
User dashboard
- Route: e.g.
/dashboard - Responsibilities:
- List publications owned by the account.
- When i click on publication i am taken to publication dashboard
- Primary action: Create publication.
- List publications owned by the account.
No public-facing representation.
Publication dashboard
- Route:
/publication-slug/dashboard - Responsibilities:
- Create and manage posts.
- Manage publication-level settings and metadata.
- Thsi can reuse most of current user dashboard which moves to publication level
This becomes the main working surface for most users.
Public publication page (new)
- Publication root URL renders:
- Chronological list of posts (blog index).
- Fills a current gap where publication URLs are empty.
Configuration changes vs current Data Hub
- Current sites are reinterpreted as posts.
- Configuration currently attached to sites/posts (e.g.
config.js) moves up to the publication level. - Existing site dashboard logic (e.g. from Flower Show) is reused at the publication layer.
- Deeper refactoring can be phased; MVP focuses on:
- reassociation (user → publication → post),
- routing,
- basic dashboards.
Explicit non-goals (for MVP)
- No public user profiles.
- No author URL resolution.
- No subdomains for publications.
- Deleting publications
- Renaming publications
Open questions (intentionally deferred)
- Whether publication dashboards use
/dashboard,/_dashboard, or a reserved segment. - When (and whether) to expose
/@usernamepublicly. - Whether publications later move to subdomains.
Tidied Transcript (Edited for Clarity)
We have a publication object, which corresponds to what are currently called sites. Those should really become posts.
Users — or better, accounts — own publications, and publications own posts.
Users do not need to exist in URL space at all. There’s no real need to address a user publicly, like
@rufus, the way Substack does.When you sign up, your username gives you a default publication at that URL. You can immediately start blogging there. You might be prompted to name the publication, but you don’t have to choose a new URL.
Later, you can create another publication, like
/datopian, if the name doesn’t collide.The base publication URL should just work. Right now, going to that URL shows nothing — that’s a missing feature. It should list posts, like a normal blog index.
I don’t think we should introduce
/p/or similar into the URL. Keeping/publication/postis cleaner, more GitHub-like, and avoids redirects.There should be a user dashboard that lists publications, and each publication should have its own dashboard under its own namespace.
If we ever move to subdomains later, this structure migrates cleanly.
A lot of the existing site dashboard work in Flower Show can be reused at the publication level. Configuration that currently lives on sites should move up to publications.
This is a deeper refactor long-term, but for now, this is the minimal change needed to get publications working properly.
Appendix: why we have this url structure
We have three distinct concepts that want representation:
- Accounts (people / organizations)
- Publications (editorial entities)
- Posts (content)
You want:
- Publications to be first-class and simple.
- Authors/accounts to be referenceable (for attribution, “written by”, links).
- URLs that feel obvious and not over-nested.
Trying to collapse all three into a single URL namespace inevitably produces discomfort somewhere.
Option A: Publication-first URLs (what you are leaning toward)
Example:
/rufuspollock→ publication/rufuspollock/my-post
Authors are referenced logically, not by URL:
- Post metadata includes
authors: [account_id] - UI renders “By Rufus Pollock” but does not require
/@rufuspollockto exist.
Pros:
- Extremely simple mental model.
- Matches Substack’s felt behavior (publication as identity).
- Optimized for the 90% case (one person, one publication).
- No early commitment to public user profiles.
Cons:
- Author URLs are absent or ambiguous.
- A publication that happens to equal a username is semantically overloaded.
This is acceptable if you treat author pages as a later concern, not an MVP concern.
Option B: Dual namespaces (explicit but heavier)
Example:
/@rufuspollock→ account/datopian→ publication/datopian/my-post
Pros:
- Clean conceptual separation.
- Clear attribution targets.
- Future-proof for multi-author publications.
Cons:
- More routing complexity.
- More concepts exposed early.
- Users must reason about two public identities.
This is architecturally “correct” but product-heavier than your current intent.
Option C: GitHub-style nesting (you are right to dislike this)
Example:
/rufuspollock/datopian/my-post
Pros:
- Perfect disambiguation.
Cons:
- Editorially awkward.
- Visually noisy.
- Strongly implies ownership hierarchy that you explicitly want to downplay.
Your instinct to avoid this is sound for a publishing product.
A pragmatic MVP resolution
For an MVP, the cleanest move is:
-
Treat publications as the only public URL entity.
-
Allow publications to have:
- a primary owner (account)
- zero or more authors (accounts)
-
Store authorship explicitly in post metadata.
-
Render author names everywhere, but do not guarantee author URLs.
If, later, you introduce author pages:
- You can add
/@namewithout breaking publication URLs. - Publications created at usernames remain valid.
- You avoid migrations and redirects.
This is the same deferred-identity strategy used by many systems that start publication-first and add social graph later.
The key principle
Do not let potential future social features force present-day URL complexity.
Your current users want to:
- publish
- read
- subscribe
They do not yet need:
- navigable author graphs
- canonical personal homepages
- identity resolution across publications
You can safely postpone that without painting yourself into a corner.
If you want, next we can:
- formalize authorship metadata minimally, or
- sketch how
/@accountcould be introduced later without breaking anything.