Only business requirements we have is that A user wants to create a list of steps to follow to get a common task done
So the Domain model can be a DO IT YOURSELF Task
, which has the task description and a list of steps to finish the task.
interface Task {
description: string
steps: Array<Step>
author: User
}
A Step
has instructions that allows a user to get part of the task done.
- A Step can be a Text
- A Step can be an Image
- A Step can be a Video
- NOTE that for clarity, a Step must have one and only
interface Step {
order: number
contentType: enum // TEXT, IMAGE, VIDEO
content: Text | Image | Video
}
interface Text {
description: string
}
interface Image {
mediaType: string
url: STRING
}
interface Video {
mediaType: string
url: string
}
Now we need a way to store user credentials and profile
interface Auth {
tokenType: string
token: string
}
interface User {
name: string
email: string
isContractor: boolean
}
interface StateModel {
auth: Auth
me: User
tasks: Array<Task>
shared: Array<Task>
}
- NOTE that since we are planning to use
mastermind
library for state management, we will modify the structure of the state model a little.- We'll be replacing
Array
withImmutable.Map
everywhere in our store. Ex.Array<Step> => Immutable.Map<String, Step>
where the key in this map is an id of the object being saved.
- We'll be replacing
interface StateModel {
appState: { isFetching: {}, errors: {}. modals: {} },
auth: { user: User, auth: Auth }
data: { tasks: Immutable.Map<String, Task>, shared: Immutable.Map<String, Task> }
}
- How do we create, update, and delete tasks?
- how do we share tasks with other users?
import { createTaskUrl } from './Api' // TODO
mastermind.update('genericApiUpdate', {
serviceOptions: {
url: createTaskUrl,
method: 'POST'
data: task
},
successActions: {
addTaskToStore: {
locationFunction: ({ res }) => {
const taskId = res.data.task.id
return ['data', 'tasks', taskId]
},
operation: 'setIn',
valueFunction: ({ res }) => res.data.task
}
},
failureActions: {
recordFailure: {
location: ['appState', 'errors', 'createNewTask'],
operation: 'setIn',
valueFunction: ({ error }) => error
}
},
})
import { createStepUrl } from './Api' // TODO
mastermind.update('genericApiUpdate', {
serviceOptions: {
url: createStepUrl,
method: 'POST'
data: { taskId, step }
},
successActions: {
addStepToStore: {
locationFunction: ({ res }) => {
const stepId = res.data.step.id
return ['data', 'tasks', taskId, 'steps', stepId]
},
operation: 'setIn',
valueFunction: ({ res }) => res.data.step
}
},
failureActions: {
recordFailure: {
location: ['appState', 'errors', 'createNewStep'],
operation: 'setIn',
valueFunction: ({ error }) => error
}
},
})
import { deleteStepUrl } from './Api' // TODO
mastermind.update('genericApiUpdate', {
serviceOptions: {
url: `${deleteStepUrl}/${taskId}/step/${stepId}`,
method: 'DELETE',
},
successActions: {
deleteStepFromStore: {
locationFunction: ({ res }) => {
const stepId = res.data.step.id
return ['data', 'tasks', taskId, 'steps', stepId]
},
operation: 'removeIn',
value: null,
}
},
failureActions: {
recordFailure: {
location: ['appState', 'errors', 'deleteExistingStep'],
operation: 'setIn',
valueFunction: ({ error }) => error,
}
},
})
import { deleteTaskUrl } from './Api' // TODO
mastermind.update('genericApiUpdate', {
serviceOptions: {
url: `${deleteTaskUrl}/${taskId}`,
method: 'DELETE'
},
successActions: {
deleteTaskFromStore: {
locationFunction: () => (['data', 'tasks', taskId]),
operation: 'removeIn',
value: null
}
},
failureActions: {
recordFailure: {
location: ['appState', 'errors', 'deleteExistingTask'],
operation: 'setIn',
valueFunction: ({ error }) => error
}
},
})