The short of it, imho:
- your user stories are too atomic, they're not stories but rather steps
- it however shows a possible room for improvement in terms of backend design: how "mature" is your API? how modular your backend (microservices vs monolithic, scalability/concurrency, etc)
- at a fundamental level you're on the right track and if you reverse the flow of thinking — which is the point of user stories in Agile — you would probably know just what to fix/change in your backend to remove some of the problematic dependencies found in stories or between steps. There's no two ways: it's either linear thus dependencies become a non-problem, or it's multi-path and you have to design for that, thus flatten the interface and expose independent "verbs".
I realize it's a bit dry so I'll try to elaborate enough, in practical terms. Also possibly a discussion at the end.
About the atomicity of stories
Here's how I think of it, back to basics: a story is not a sentence (task: "I opened the menu"). A story is a not even a group of sentences — that's a paragraph ("I wanted to change a setting. I opened the menu. I looked for a familiar "settings" or "parameters" icon/text. I found it and opened it. The "theme" setting was first in line.").
- Each sentence is supposed to express 1 thought,
- each paragraph is supposed to express 1 idea, 1 "point", 1 "scene" or "shot" (think storyboard, comics, movie editing).
- A "story" is a collection of such paragraphs or scenes/shots.
Even if they're one liners, at least, we have:
- a premise (who*/when/where from),
- a plot (what? why?),
- a development (how?)
- and a resolution (where/how do we end? options from there? => paths to other "base" story clusters).
* We want different "persona" to test against, link with BI/analytics if possible.
As a side note, "UX" is when we've got a more-or-less unified set of "paths" whose salient points should be exactly our user stories.
It's important to retain all of that substance in order to "understand" the story. A good idea is to imagine it as a comics: usually 1 page at most, but typically more than 1 vignette (or it better be damn expressive!)
I feel like we could make 1 'main' or 'base' story there, e.g. tell the story of "a user signs up normally"; then make ad hoc variation/fork stories if necessary.
The "maturity" of a backend interface
Our API-s should be as "expressive" as the codebases they link.
There's the backend/upstream on one side, and the client/user "experience" (collection of all their stories) on the other side. In the middle, your API. From a dev standpoint, the API's expressivity often dictates (limiting or enabling) how much you can "play" with the codebase. From the user standpoint, even if it's invisible, it dictates how "fluent" or "stuttering" they feel when trying to express themselves through the application.
I find that when dependencies tend to creep up in the simplest user stories that you nonetheless wish to enact, it's usually due to upstream constrains — i.e. backend either not micro-servicing enough (too "monolithic"), or API not "mature" enough.
The problem is thus possibly not related to how we chunk our user stories — a sign of that is those dependencies showing up no matter what — but deeper to how we structured the backend interface. That would be my intuition.
Avoid "epics" like we avoid "god methods" to solve such problems. Rather seek to solve at the most essential / lowest level: actually remove the dependency through architectural change, rather than work around it — before we know it, it's become a minefield like npm
.
Agile/scrum, in that view, isn't the problem but part of the solution: it helped identify the issues (good job, next/new problem = progress). It will help us design the solution.
So it doesn't mean that it's bad, it's a design decision that has to be made.
Hear, hear! (SO, Martin Fowler!)
Oh look, Fowler again!.. this time on the Richardson maturity model.
Discussion (1) Human Centered Design
Is that thinking differently? I'll let you be the judge of that. I think it's simply zooming out, taking some perspective, seeing the flow.
So what is the flow? Think back to a fundamental purpose of Agile/scrum: to design faster so we are closer to the end user. Shorten the cycle, you shorten the "shipping" part of the feedback loop.
Enter "user-centered design".
Basically an offspring of Human Centered Design, itself part of Interaction Design. Lots of good food for thought in those articles,
[Human-centred Systems] involves a radical redesign of the interface technologies and at a philosophical level the objective is to provide tools (in the Heidegger sense) which would support human skill and ingenuity rather than machines which would objectivise that knowledge".
Inception time: Agile too is one such "human centered system" at heart, compared to some diktat of the machine circa UNIX 1980s.
User stories, as a tool (for developers), aim at reversing the traditional top-down "developers mouth-feed whatever they think best down into users throat" (in this model, "upstream" is dominant) towards a "bottom-up" model. Because in Agile we consider user stories first, as a basis, we start from "downstream" and develop "up" so that our work ends up being shaped, from the onset, by its users, or more specifically their experience.
This, imho, is one of the greatest merits of the Agile paradigm (et. al: scrum, devops, etc), and should survive it even. It's just a golden principle of great product design regardless of the field. [Apparently was already true in good old Babylon...]
Again my subjective observation, but it seems the trend towards microservices and beyond (serverless / functional programming), the modularity of virtualization (the success of LXC/LXD containers, from Docker to K8 passing by Red Hat solutions etc.) and software-defined everything, CI/CD or the 'devops' culture... all of this seems to follow/build one silver thread: to enable infrastructure (and its makers, us) to support the above shift towards user-centered design. It's just necessary too, when every living person and their cat has become a walking multi-site network relying on hundreds of remote services.
Discussion (2) The Art and Freedom to Design
There's too much noise out there, and we lose track of the essence... We replay 'human stories' and ironically forget that, as devs, this is a just a tool, for we are literal gods in this application we're writing ourselves. This is a great power and it comes with great responsibility in a bottom-up paradigm: at the end of the day, we design-ed for users whether we realize-d it or not, whether we take/took it into account or not. We might say, for instance:
ie, you can't really choose a username until you've signed with an account
But that's our choice as devs, not a fact. It's only true for some applications/workflows.
Were these decisions motivated by user stories, thinking of user experience? Or thinking in terms of designing a good application, a good backend, a good security practice i.e. make developers happy?
Zoom out. We could perhaps do otherwise. If we want to. Do we? Will we?
What I mean is that our decisions, all of them, tend to impose some constrains on "the set of possible stories". And that's good, as long as we're fully cognizent of that. Sometimes more important than "what does this code change add to the table?", always consider the devil's advocate plea: "what does it remove? what does it deny us that was allowed before/without?"
You've designed in a way that imposes the constrains you now meet. Own that, the 'why' and 'what', because it frees you to plan your next step with maximum agility indeed.
We like "modular" "microservices" because it tends to leave the architecture opened to change, but really there's a happy medium to strike (user stories and API maturity help you find the sweet spots, as you seek/find how to make the two meet in harmonious accordance, and design around the interface, starting from there rather than having it as a distant edge concern).
Again, there is no good or bad, just decisions and results; but owning the whole user-centered/downstream-up process, even if/when we were clearly swimming downwards from our ivory tower, is how we increasingly remove our limiting thoughts (the "can't") and open ourselves to see other possibilities, try other things.
Obviously we can't rewrite the whole thing now. It's a long-term marathon, but the magic of this endless short-cycle self-evidently lies in compound effect, quick iterations, small fixes that build up to major refactorings in time, as integral part of the CD process (we build and maintain at once).
I hope this helps, even at a high level (can't do much more in abstraction). Don't hesitate to ask further questions.