This document is an attempt to pin down all the things you don't think about when quoting for a project, and hopefully provide a starting point for some kind of framework to make quoting, working and delivering small-medium jobs more predictable and less stressful.
The hardest bit of any job, and lots of pitfalls
Estimating the work
- the actual work of what you see on screen will only be a fraction of the work to do
- you can estimate the steps needed "to do a thing" but not always the complexity of the steps
- don't underestimate "the work to do the work", "the work between the work" and "the work around the work"
Price for value
- if you can do something others can't, price accordingly
- if the hassle for the client starting again, or going elsewhere is prohibitive, price accordingly
You need to account for working with unfamiliar services
Domain knowledge
- multi-domain or multi-dependency projects are more difficult (naming, objects, APIs, etc)
Do you know the technology?
- knowing something exists is very different from knowing it inside out
- it may be difficult or even extremely difficult to learn, meaning you spend a long time writing bad code
- it may turn out to be unsuitable after all
- you may not properly learn it and create a mess which will need to be cleared up at some point
Picking the right technology
- Nuxt vs Vue
- Elastic vs Postgres
- Azure vs ???
You may be skilled, but it's highly unlikely you will know everything you need to
You won't know what you don't know
- you may need to learn new skills (elastic, nuxt, some api, etc)
- you may not know this until it comes time to actually do the work
- this could significantly impact your timelines / profit margins / client relationship
- is there any way to predict this in advance?
Your current skills may be adequate for small but not medium or large jobs
- relying on basic skills may get you over the line, or may bite you later in the project
- how should you tackle this? Level up? Subcontract? Who will pay for this?
Unforeseen problems
- you will underestimate the difficulty of some tasks
- you will underestimate the timings on some tasks
- you may have showstoppers where you can't go on
- how should you predict / manage / cost for these?
Third party tools
- save time by using something already made for the job
- note that depending on the scale of the tool, it will still take time to learn
First party tools
- sometimes, you have to build it yourself
- time saved learning something else may be taken up in planning, development, debugging, refactoring, packaging, documenting
- a tool could take a few days or a few weeks, and will require ongoing maintenance and updates
You need to put a lot of things in place before you can do the actual work
Project setup (these could all be separate sections!)
- config and build setup
- keys and security
- 3rd-party dependencies
- component library
- initial folder structure
- routing and layouts
- Api
- login and logout
- store and state
- additional services
- individual utilities
- repositories and deployment
Dependencies
Design
- new layouts to think about
- the ui kit does not account for many use cases, and does not cover layout
- figuring out how all the ui components should fit together in your layout may take longer
- compound UI components may take longer
Also see "the work between the work"
POC is completely different from something the client / users will be happy with
Developing the actual code (utility, library, service, component, feature, module, app)
- POC is bare minimum to show it can work, crap UI, can only be used by devs
- Alpha is first rough working version, that can be used by (brave!) humans
- Beta / MVC is mainly working, but there may be bugs
- Release is working, big-free, polished, potentially documented and with tests
Getting the details right takes time
- the 80/20 rule of getting things perfect
- changing your mind or making something better
- realising that you were doing it wrong
- iterating (getting it working, vs getting it right) to the best solution
- keeping things consistent
Examples
- API with notifications
- form interaction
- form validation
- modals
Stuff that if it wasn't there would look broken
- empty states
- loading indicators
- error handling
- notifications
Design and finish
- adding the polish to make it look nice
- fixing bugs which may or may not be your fault
Quality control
- adding tests
- adding support like storybook
- writing documentation
Any project longer than a few weeks has invisible costs built in
Note: these kinds of changes are invisible to the client!
Debugging
- your own code because it's not working as expected
- third party code or configuration because it doesn't support something you need
Configuration
- updating or fixing configuration
- keeping up with framework changes and patches
Tooling
- updating build tools to make things faster / more reliable
- building dev tools to help you do the work
- introducing new processes and tools
General maintenance as you go along
- building systems to keep things DRY
Migrations
- could be database, services, anything
- planning a migration
- running two sets of code
- implementing the migration
Refactoring
- stitch-in-time updates (even if out of scope) so it doesn't turn to shit
- larger refactors to prevent spaghetti or make hard things possible
- updating older systems as you find bugs or expand functionality
Defactoring
- as requirements change, you may even need to take functionality out!
- removing complexity can sometimes be as hard as adding it
Design
- what is works in once place today, may not work in two places tomorrow
- new layouts or components may be required (dropdown, modal, notification)
- as the app gets more advanced, more components will be expected to work together
Requirements
- expectation management / negotiation (over or under / difference of opinion)
- omissions
Changes
- client changes
- feature creep
- mission creep
Larger projects have different constraints and inherent increased complexity vs small projects
Going from small to medium
- think about thresholds when going from a simple app to a complex app (routing, store, tools, etc, etc)
- once the application grows, consistency is an issue; adding new layouts to old, keeping track of components
- you'll need to scale up things like naming conventions, css file structure, store paths, etc
- taking time to make the styling consistent as it scales
Increased size will (in part) mean increased complexity
- complexity can increase as more features are added ((n*(n+1))/2)
- coupled features means more dependencies
- something which was quick to edit at a small scale may slow down as the project grows
- need to account for more time moving between sections of the application
Shortcuts
- shortcuts taken in a small project will likely not scale well in a larger project
- for example, window.prompt, password protected folders,
Hierarchies
- meaning folders, routes, APIs
- as the app grows you may need to introduce additional levels
State
- local state is easy, but not flexible
- need to access same state from two different places? Make it global
- the calls and format will be different
- you may need additional tooling like Vuex Pathify
- or, it may bemore complex than a simple vuex store
- might need to build services, use a new technology, or something else
Persistence
- initial state / loading
- saving the data
- loading the data
- using cookies, localstorage, URL, database
Things you could get away with in a small project, you might not in a big project
- updating the URL with form changes
There will always be a significant amount of work around the work
Experiments
- reading docs
- trying out libraries
- code sketches
Internal work
- code reviews
- writing issues
- repository management
Client management
- meetings
- reviews
Once the project is live, or nearly live, there is still work to do
Sections
- hosting
- deployment
- updates / upgrades
- bug fixes
- security
Often the "work" is only a fraction of the work.
Phrase | Meaning |
---|---|
The work to get the work | Planning, quoting, pitching |
The work before the work | Setup, configuration, prototyping |
The work | The actual build, product, etc |
The work between the work | Debugging, development, refactoring, tooling, maintenance |
The work beyond the work | Omissions, scope creep, mission creep |
The work around the work | Client meetings, code reviews, project management, etc |
The work after the work | Hosting, deployment, support, security |
See final article here.
Thanks!
I realised that there's probably also "the work after the work" which is hosting, support, security, etc, etc. Not sure how far this analogy can go, but it does make sense.
Good suggestions as well. I will think about how to add them in.
I feel like the overall "project management" side of things could be a separate article; my thoughts so far have mainly been about identifying the physical nuts and bolts rather than how to organise the delivery of them.