---
# System prepended metadata

title: 'Income: More Technical Post-Mortem'

---

# Income: More Technical Post-Mortem

## intro comments
- These don't apply for simpler components like the HistoryHurdle, which is a table to show a model, and a form to update that model.
- It's more for "composite" components. Page-level components that have different data types, complicated forms, multiple endpoints, etc.
    - Income
    - Documents
- Reducing mental load and the need for "hunting" down information: Things I'll try to start doing more, so the intent of the code clearer and to make implicit things more explicit. 

##  Increase typing for formstate and payloads.
- The inputs on a form don't always match up with endpoints 1:1
- Sometimes endpoints will expect a diff of changes, sometimes the updated object itself
- Intersection types can help us build a more composable set of types that allow for that flow between the back-end struct<=>how it's held in form state<=>how that formstate maps to payloads
 - LOTS of differing opinions on how to name the types, on _which things_ deserve types
 - "Local" types for forms? Hm...


## Possible code-smell: `renderX` functions
- Instead of using "smaller" components, we use `renderThing()` functions which can result in huge files, which in turn obfuscate how things are tied together. Some variable or hook that's used on line 800 might be declared on line 100.
    - Which functions use what hooks?
    - What is in scope at any given time?
    - Namespace collisions 3x
- This is convenient because we don't have to pass things around, we can have functions that do transformations of data shapes, API calls, and UI orchestrations in the same place.

## A tad more componentization
- Navigability is hard for super long components
- Prevents over-sized page-level components
- Prevents over-sized `helper.ts` files

## Comments: JSDoc comments
- In one sense, stray comments are one of the main sources of code cruft. In other sense, adding more comments is an insanely valuable way to share highly-contextual product knowledge without incurring extra communication overhead.

## Product context comments
- Without this, requires a trace of the functions to understand what's going on, which is really hard because of all the issues below. 
- I've had the distinct feeling of "mental stack overflow" which isn't common. The last time I had this feeling was when first learning about redux action creators like `const x = () => () => () => {}`

## Storing things as arrays with helpers to retrieve functions
We need a pattern for this:
- income_aggregations
- document_fields

We currently handle this with helpers `getXfromList()` and local maps to map a key to the value. Brittle and confusing.

## Class-based components
- Not necessarily a problem in itself just `componentWillReceiveProps`
    - Deprecated lifecycle hooks
    - Prop -> state, then dumping of state
        - https://reactjs.org/docs/react-component.html#unsafe_componentwillreceiveprops


## API Update Payload Differences
```jsx
const updateX = (id, data) => {}
const updateY = (dataWithID) => {}
const updateZ = (dataContainingSomeOtherUniqueKey) => {}
```

## Conventions to consider

### TLDR:

- More consciously account for the cost of properly handling this overhead work when it comes to larger components. To that end, on select occasions, turning a 5-pointer into an 8-pointer makes sense to me. Adding, editing types, thoughtfully adding documentation and comments.
    - If we permit the creation of a 1-pt story for a text change, I think this concept is fair, accurate, and will prevent over-committing and silent burnout
- Let's componentize as-needed for long-lived components and page-level components, where the cost of additional indirection yields an overall benefit in code readability and navigability
- "Soft-require" JSDoc-style comments on util/helper functions