- File Structure
- Best Practices
- Naming Conventions
- Visual Studio Code
- Development
⚠️ In progress.
src/
├ api/ # Tests
├ domain/ # Tests
│ ├ slices/ # Redux slices
│ │ └ aDomain.ts
│ └ use_cases/ # Redux reducers
│ └ aDomain/
│ ├ __tests__/ # Tests
│ │ ├ getOne.test.ts
│ │ └ updateOne.test.ts
│ │ getOne.ts
│ └ updateOne.ts
├ features/ # React components
├ libs/ # Shared utility classes (one per file)
├ utils/ # Shared utility functions (one per file)
├ constants.ts # Shared constants and enums
└ utils.ts # Utility functions
A big component could look like that:
MySuperComponent/
├ __tests__/ # Tests
│ ├ aUtilityFunction.test.ts
│ └ anotherUtilityFunction.test.ts
├ index.tsx # Main code
└ utils.ts # Utility functions
null
is considered to be the most expensive mistake in the history of programmation
by its own creator.
Sindresorhus did it.
Names exports enforce a consistent naming accross the database (helping code lookup) and ensures tree shaking.
Here is a good explanation of why. In short, it ensures that no type is being accidentally trasnpiled, it eases refactoring and fasten transpilers work.
Excepted for first data loading and direct DOM manipulation when no better logic is available (nost often events).
It makes the component logic easier to understand when we separate concerns between JSX rendering / props passing and the code logic contained above.
Named functions also ease debugging stacks in comparison with expressions in props.
If multiple components must react to common state property and that components' props can't easily be passed, we must use Redux selectors / dispatches and only them to handle that state.
Local component states must be absolutely isolated. Excepted during their initialization via the component props (and nothing else!).
If internal component constants must derive from this state value during their initialization, we can use useRef()
.
If some internal component constants must derive from this state value for each change, we can use useMemo()
.
A React component is a DOM listener and renderer. Its code should only orchestrate its state changes in order to achieve these 2 roles.
Most should be extracted into small utility functions within either a local utils.ts
file or
within the global utils/
directory if they are shared by more than one component.
Not only does it lighten our components code but more importantly, it helps us unit-testing component code logic while avoiding the not-so-fun task of testing the component itself.
It helps avoiding naming conflicts with internal functions and easily differenciate what should be called from what should be dispatched.
Example:
import * as domainActions from "...";
⚠️ In progress.
It has been a forever convention for both ECMAScript and Node.js to use on
for any exposed listening function
expecting a callback. React native uplifter props follow this convention themselves.
{
"editor.codeActionsOnSave": {
"source.fixAll": true
},
"editor.defaultFormatter": "dbaeumer.vscode-eslint",
"editor.formatOnSave": true,
"eslint.codeActionsOnSave.mode": "all",
"eslint.format.enable": true,
"eslint.packageManager": "npm",
"eslint.workingDirectories": ["./frontend"],
"[json]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
}
}
In local development, the backup config file is already set up there.
You can just run the following commands:
Backup:
make dev-backup-db
Restore:
# This will recreate the database container and its volume before restoring the dump:
make dev-restore-db TAG=YYYY-MM-DD-[daily|weekly]
Example, to restore a dump directory from ./.backups/2024-04-13-daily
:
make dev-restore-db TAG=2024-04-13-daily
In a remote deployment, if not done already, you need to copy and customize the backup config file:
cp infra/remote/backup/pg_backup.config.example infra/remote/backup/pg_backup.config
The remote server database is automatically backed up using this crontab file.
This generates daily and weekly dumps in the backup directory defined via the BACKUP_DIR
var declared in
infra/remote/backup/pg_backup.config
(ex: 2024-04-12-weekly
, 2024-04-13-daily
, etc).
Backup:
make backup-db
Restore:
Important
- Stop all applications from connecting to the dababases.
- The database container and its volume must be cleared (removed and recreated) before restoring a dump.
make restore-db TAG=YYYY-MM-DD-[daily|weekly]
Example, to restore a dump directory from [YOUR_CONFIG_BACKUP_PATH]/2024-04-13-daily/
:
make dev-restore-db TAG=2024-04-13-daily
On the remote server:
# Dump the databases:
make backup-db
# Compress the dump directory:
cd YOUR_CONFIG_BACKUP_PATH
tar -cvzf YYYY-MM-DD-[daily|weekly].tar.gz YYYY-MM-DD-[daily|weekly]
Then use SCP to download the dump locally into the .backups/
directory and restore it on your local machine:
tar -xvzf ./.backups/YYYY-MM-DD-[daily|weekly].tar.gz -C ./.backups
make dev-restore-db TAG=YYYY-MM-DD-[daily|weekly]