Merge branch 'master' into dev
This commit is contained in:
commit
2e6b2e8ba2
@ -10,7 +10,7 @@ tags:
|
|||||||
notes: add some stuff about redox keyboard itself
|
notes: add some stuff about redox keyboard itself
|
||||||
---
|
---
|
||||||
|
|
||||||
In this blog post I am going to take you out on a little journey of making my own keyboard. Perhaps help you if you've decided to make yourself your own.
|
In this blog post, I am going to take you out on a little journey of making my own keyboard. Perhaps help you if you've decided to make yourself your own.
|
||||||
|
|
||||||
![Preview of Redox keyboard with RGB lights turned on in a dark](/images/uploads/img_20200301_171735.jpg 'Preview of Redox keyboard with RGB lights turned on in a dark')
|
![Preview of Redox keyboard with RGB lights turned on in a dark](/images/uploads/img_20200301_171735.jpg 'Preview of Redox keyboard with RGB lights turned on in a dark')
|
||||||
|
|
||||||
@ -18,11 +18,11 @@ But first, I want to tell you:
|
|||||||
|
|
||||||
## Why I've decided to make my own keyboard
|
## Why I've decided to make my own keyboard
|
||||||
|
|
||||||
I've been feeling pain in a wrist of my right hand for 2 years now. I've started to feel it when I started to be more physically active. I've been working out and played a lot of squash. It got to the point that I had to visit an orthopedist. I was scared that I'd have the infamous **carpal tunnel syndrome**. At this stage he said it was just strained. The pain eased out after some therapy but it still comes back and it got to the point that I had to change my work habits.
|
I've been feeling pain in the wrist of my right hand for 2 years now. I've started to feel it when I started to be more physically active. I've been working out and played a lot of squash. It got to the point that I had to visit an orthopedist. I was scared that I'd have the infamous **carpal tunnel syndrome**. At this stage, he said it was just strained. The pain eased out after some therapy but it still comes back and it got to the point that I had to change my work habits.
|
||||||
|
|
||||||
One night I was checking out the state of programming streams on _twitch_. I've found a great streamer [JMS WRN](https://www.twitch.tv/jmswrnr) and as I was chatting with him about my wrist problem he gave me a recommendation for my new mouse: [Logitech MX Vertical](https://www.logitech.com/en-us/product/mx-vertical-ergonomic-mouse?crid=7) and then he showed me that he has a _Discord channel_ just for keyboard stuff. And that was **the moment** for me. I've discovered a whole new world of possibilities around keyboards.
|
One night I was checking out the state of programming streams on _twitch_. I've found a great streamer [JMS WRN](https://www.twitch.tv/jmswrnr) and as I was chatting with him about my wrist problem he gave me a recommendation for my new mouse: [Logitech MX Vertical](https://www.logitech.com/en-us/product/mx-vertical-ergonomic-mouse?crid=7) and then he showed me that he has a _Discord channel_ just for keyboard stuff. And that was **the moment** for me. I've discovered a whole new world of possibilities around keyboards.
|
||||||
|
|
||||||
I've started to do a research around custom keyboards, their parts, _QMK software_ and its possibilities. I was 100% sure that, if I am going to make my own keyboard it would be **split and ergonomic**. It just looks so cool to be able to have one part of the keyboard away from the other.
|
I've started to do research around custom keyboards, their parts, _QMK software_, and its possibilities. I was 100% sure that, if I am going to make my own keyboard it would be **split and ergonomic**. It just looks so cool to be able to have one part of the keyboard away from the other.
|
||||||
|
|
||||||
### Some split keyboards that caught my attention
|
### Some split keyboards that caught my attention
|
||||||
|
|
||||||
@ -30,17 +30,17 @@ I've started to do a research around custom keyboards, their parts, _QMK softwar
|
|||||||
- [Quefrency - 60%/65%](https://keeb.io/collections/frontpage/products/quefrency-60-65-split-staggered-keyboard?variant=16032981385310)
|
- [Quefrency - 60%/65%](https://keeb.io/collections/frontpage/products/quefrency-60-65-split-staggered-keyboard?variant=16032981385310)
|
||||||
- [ErgoDox](https://www.ergodox.io/)
|
- [ErgoDox](https://www.ergodox.io/)
|
||||||
|
|
||||||
I got to the point when I realized, that if I want to make a keyboard, I have to make a complete shopping list. My first go to was the _Iris Keyboard_ from _Keeb.io_. But then I've found the shipping cost and that changed my decision. I was looking into other options that were accessible in Europe and then I've found [FalbaTech](https://falba.tech/), who is based in Poland which made me so excited. There are really not that many shops which are based in Europe.
|
I got to the point when I realized, that if I want to make a keyboard, I have to make a complete shopping list. My first go-to was the _Iris Keyboard_ from _Keeb.io_. But then I've found the shipping cost and that changed my decision. I was looking into other options that were accessible in Europe and then I've found [FalbaTech](https://falba.tech/), which is based in Poland which made me so excited. There are really not that many shops which are based in Europe.
|
||||||
|
|
||||||
I took a look at his selection of custom keyboards and decided on the **Redox keyboard**. It is a split orthodox keyboard heavily inspired by **Ergodox**. There are two options for this keyboard: Classic wired and wireless. I've decided for a wired one as I didn't want to complicate my first build.
|
I took a look at his selection of custom keyboards and decided on the **Redox keyboard**. It is a split orthodox keyboard heavily inspired by **Ergodox**. There are two options for this keyboard: Classic wired and wireless. I've decided on a wired one as I didn't want to complicate my first build.
|
||||||
|
|
||||||
If you want to take a closer look into Redox keyboard and its details, I recommend reading designer's [Hackaday.io page](https://hackaday.io/project/160610-redox-keyboard)
|
If you want to take a closer look into the Redox keyboard and its details, I recommend reading the designer's [Hackaday.io page](https://hackaday.io/project/160610-redox-keyboard)
|
||||||
|
|
||||||
## Let's make a shopping list
|
## Let's make a shopping list
|
||||||
|
|
||||||
You might think that making a custom mechanical keyboard can be cheap but the opposite is quite true. The electronics are the cheapest part and they are not that hard to get. You might find many of them in the nearest radio amateur shop. Parts that you have to reconsider and are most important are the PCB, case, switches and keycaps.
|
You might think that making a custom mechanical keyboard can be cheap but the opposite is quite true. The electronics are the cheapest part and they are not that hard to get. You might find many of them in the nearest radio amateur shop. Parts that you have to reconsider and are most important are the PCB, case, switches, and keycaps.
|
||||||
|
|
||||||
For my build, as it is my first one, I had to also buy soldering iron and various tools.
|
For my build, as it is my first one, I had to also buy a soldering iron and various tools.
|
||||||
|
|
||||||
I decided that I want my custom case and my friend was so kind that he asked his brother to **3D print** it for me.
|
I decided that I want my custom case and my friend was so kind that he asked his brother to **3D print** it for me.
|
||||||
|
|
||||||
@ -65,7 +65,7 @@ You will also need some cables so make sure that you will buy everything you nee
|
|||||||
|
|
||||||
So this makes a total of ~115 € for only components of the keyboard itself and these are very cheap compared to the commercial market where you could pay this price for keycaps only.
|
So this makes a total of ~115 € for only components of the keyboard itself and these are very cheap compared to the commercial market where you could pay this price for keycaps only.
|
||||||
|
|
||||||
I also had to buy some tools, so I could make this project a reality. There is a nice sum up of tools you'll need at [keeb.io](https://docs.keeb.io/soldering-tools/).
|
I also had to buy some tools, so I could make this project a reality. There is a nice sum-up of tools you'll need at [keeb.io](https://docs.keeb.io/soldering-tools/).
|
||||||
|
|
||||||
- [60W Soldering Station](https://www.banggood.com/MUSTOOL-SD1-SD2-LCD-60W-Soldering-Station-Professional-PID-Soldering-Iron-Station-4-in-1-Tool-Kit-Adjustable-Temperature-200-480C-with-Solder-Wire-Holder-p-1590175.html?rmmds=myorder&ID=471846280495&cur_warehouse=CN) - ~25€
|
- [60W Soldering Station](https://www.banggood.com/MUSTOOL-SD1-SD2-LCD-60W-Soldering-Station-Professional-PID-Soldering-Iron-Station-4-in-1-Tool-Kit-Adjustable-Temperature-200-480C-with-Solder-Wire-Holder-p-1590175.html?rmmds=myorder&ID=471846280495&cur_warehouse=CN) - ~25€
|
||||||
- [Anti-static Tweezers](https://www.banggood.com/ESD-10-15-Safe-Anti-static-Tweezer-Maintenance-Repair-Nippers-Forceps-p-1102662.html?rmmds=myorder&ID=514829&cur_warehouse=CN) - ~1€
|
- [Anti-static Tweezers](https://www.banggood.com/ESD-10-15-Safe-Anti-static-Tweezer-Maintenance-Repair-Nippers-Forceps-p-1102662.html?rmmds=myorder&ID=514829&cur_warehouse=CN) - ~1€
|
||||||
@ -79,7 +79,7 @@ For a total of ~49€ for tools needed.
|
|||||||
|
|
||||||
## Assembly time
|
## Assembly time
|
||||||
|
|
||||||
So I waited a few weeks for the goods to arrive home and after everything that was needed for the assembly came I've scheduled the assembly to be done over the weekend. First weekend had came by and I was not feeling it, so I moved it to the next one when I was sure I wouldn't be interrupted by anyone. It fit very well because I was soldering the keyboard over the night that was on a day of parliamentary elections. I knew that I was going to be up very late anyway.
|
So I waited a few weeks for the goods to arrive home and after everything that was needed for the assembly came I've scheduled the assembly to be done over the weekend. The first weekend had come by and I was not feeling it, so I moved it to the next one when I was sure I wouldn't be interrupted by anyone. It fit very well because I was soldering the keyboard over the night that was on a day of parliamentary elections. I knew that I was going to be up very late anyway.
|
||||||
|
|
||||||
### 1. Prepare your workplace
|
### 1. Prepare your workplace
|
||||||
|
|
||||||
@ -91,15 +91,15 @@ So this is how the keyboard looks like when you pack it up into a shoe-box:
|
|||||||
|
|
||||||
### 2. Solder switching diodes
|
### 2. Solder switching diodes
|
||||||
|
|
||||||
What's nice about keyboard assembly is that, when you are going to solder for the first time or like me the second time after 12 years, it starts from the simplest tasks to the hardest. In the end it is simple all the way because after first 70 soldered joints you will get into it and you will learn how the solder behaves.
|
What's nice about keyboard assembly is that, when you are going to solder for the first time or like me the second time after 12 years, it starts from the simplest tasks to the hardest. In the end, it is simple all the way because after the first 70 soldered joints you will get into it and you will learn how the solder behaves.
|
||||||
|
|
||||||
PCBs of Redox are the same for both sides. That means you will put diodes on the opposite side of the PCB that it is going to be used for second hand.
|
PCBs of Redox are the same for both sides. That means you will put diodes on the opposite side of the PCB that it is going to be used for the second hand.
|
||||||
|
|
||||||
![PCB with soldered switching diodes](/images/uploads/2020-03-23_20-24-08_235.jpg 'PCB with soldered switching diodes')
|
![PCB with soldered switching diodes](/images/uploads/2020-03-23_20-24-08_235.jpg 'PCB with soldered switching diodes')
|
||||||
|
|
||||||
Remember that the **direction of the diodes matters** and that means the black part of the diode should be placed at the square on the PCB!!!
|
Remember that the **direction of the diodes matters** and that means the black part of the diode should be placed at the square on the PCB!!!
|
||||||
|
|
||||||
When you are done with soldering be careful while cutting the pins. They are going to fly across whole room. Also you should wear protective glasses if you are not able to point them to be shooting away from you. I was able to find some pins after 2 weeks in the corners of the room.
|
When you are done with soldering be careful while cutting the pins. They are going to fly across the whole room. Also, you should wear protective glasses if you are not able to point them to be shooting away from you. I was able to find some pins after 2 weeks in the corners of the room.
|
||||||
|
|
||||||
### 3. Solder momentary switches
|
### 3. Solder momentary switches
|
||||||
|
|
||||||
@ -107,23 +107,23 @@ Momentary switches are used to send a reset signal to the Pro Micro. They are go
|
|||||||
|
|
||||||
### 4. Solder TRRS sockets
|
### 4. Solder TRRS sockets
|
||||||
|
|
||||||
They will provide a way for connecting two sides together so you would only use one USB connection with computer.
|
They will provide a way for connecting two sides together so you would only use one USB connection with a computer.
|
||||||
|
|
||||||
Also, if you decide to install RGB backlights, the coordinating signal is going to be wired through the socket pin as well.
|
Also, if you decide to install RGB backlights, the coordinating signal is going to be wired through the socket pin as well.
|
||||||
|
|
||||||
### 5. Solder the head pins for the Pro Micro
|
### 5. Solder the header pins for the Pro Micro
|
||||||
|
|
||||||
By head pins I mean the small pins that are supposed to hold the Pro Micro above the PCB.
|
By header pins, I mean the small pins that are supposed to hold the Pro Micro above the PCB.
|
||||||
|
|
||||||
Don't solder the Pro Micro yet! You won't be able to put the switches onto the board.
|
Don't solder the Pro Micro yet! You won't be able to put the switches onto the board.
|
||||||
|
|
||||||
![Head pins of Pro Micro soldered into the PCB](/images/uploads/2020-03-23_20-24-06_393.jpg 'Head pins of Pro Micro soldered into the PCB')
|
![Head pins of Pro Micro soldered into the PCB](/images/uploads/2020-03-23_20-24-06_393.jpg 'Header pins of Pro Micro soldered into the PCB')
|
||||||
|
|
||||||
At this point, you would notice that the USB port is going to be very low and not very tight on the left side. Please be aware of this. If you want to, you can also just wire some leftover pins from the diodes and make them shorter but I was doing OK with the head pins of the Pro Micro.
|
At this point, you would notice that the USB port is going to be very low and not very tight on the left side. Please be aware of this. If you want to, you can also just wire some leftover pins from the diodes and make them shorter but I was doing OK with the header pins of the Pro Micro.
|
||||||
|
|
||||||
### 6. Mount the switches
|
### 6. Mount the switches
|
||||||
|
|
||||||
Try to put at least few switches on the case and try mounting them on the board. The PCB has holes in it to mount the switches so it should fit together. Mine didn't so I had to make a little hack on a few switches so they wouldn't bend my board by cutting their bottoms.
|
Try to put at least a few switches on the case and try mounting them on the board. The PCB has holes in it to mount the switches so it should fit together. Mine didn't so I had to make a little hack on a few switches so they wouldn't bend my board by cutting their bottoms.
|
||||||
|
|
||||||
![Cutting switch bottoms to be able to put them in the case](/images/uploads/2020-03-23_20-24-15_387.jpg 'Cutting switch bottoms to be able to put them in the case')
|
![Cutting switch bottoms to be able to put them in the case](/images/uploads/2020-03-23_20-24-15_387.jpg 'Cutting switch bottoms to be able to put them in the case')
|
||||||
|
|
||||||
@ -133,13 +133,13 @@ All of the switches should have their feet on the other side of the board. Try t
|
|||||||
|
|
||||||
### 8. Solder the Pro Micro
|
### 8. Solder the Pro Micro
|
||||||
|
|
||||||
Almost done with the solder. Now it's time to wire the brains of the keyboard. These joints are going to be the best. There is not that much room so you'll have to bring your A game here.
|
Almost done with the solder. Now it's time to wire the brains of the keyboard. These joints are going to be the best. There is not that much room so you'll have to bring your A-game here.
|
||||||
|
|
||||||
To be honest, I had to revisit and try to fix both of my Pro Micros. One full column of my keyboard was not working because of one bad contact. I was trying to unmount whole Pro Micro out but wasn't able to suck the solder out so I desperately just tried it out again and it worked. I just needed to apply more heat to it. Few days later, my Enter key was not working and it was the same problem, but on the other side.
|
To be honest, I had to revisit and try to fix both of my Pro Micros. One full column of my keyboard was not working because of one bad contact. I was trying to unmount the whole Pro Micro out but wasn't able to suck the solder out so I desperately just tried it out again and it worked. I just needed to apply more heat to it. A few days later, my Enter key was not working and it was the same problem, but on the other side.
|
||||||
|
|
||||||
Before you proceed to the next step:
|
Before you proceed to the next step:
|
||||||
|
|
||||||
The USB ports on the Pro Micro are infamous to break when you manipulate a lot with them. I've decided that I want to have my right hand side as a master and the USB port broke after 3 days. I was not able to burn a new firmware on it but I had to rewire the RGB backlight and I use my left hand side as a master. On the left hand side the USB port is sitting between the board and Pro Micro so it should be harder to break. Be careful with them anyway!
|
The USB ports on the Pro Micro are infamous to break when you manipulate a lot with them. I've decided that I want to have my right-hand side as a master and the USB port broke after 3 days. I was not able to burn a new firmware on it but I had to rewire the RGB backlight and I use my left-hand side as a master. On the left-hand side, the USB port is sitting between the board and Pro Micro so it should be harder to break. Be careful with them anyway!
|
||||||
|
|
||||||
### 9. Wire RGB backlight
|
### 9. Wire RGB backlight
|
||||||
|
|
||||||
@ -147,17 +147,17 @@ Find some small cables that are flexible and wire them according to this: https:
|
|||||||
|
|
||||||
## Burning the firmware
|
## Burning the firmware
|
||||||
|
|
||||||
I'll recommend to get to know QMK software. You can do so here: https://qmk.fm/
|
I'll recommend getting to know QMK software. You can do so here: https://qmk.fm/
|
||||||
|
|
||||||
Check it's abilities and _Getting Started_ section
|
Check it's abilities and _Getting Started_ section
|
||||||
|
|
||||||
But to sum up what I did it was pretty simple:
|
But to sum up, what I did was pretty simple:
|
||||||
|
|
||||||
1. `git clone https://github.com/qmk/qmk_firmware`
|
1. `git clone https://github.com/qmk/qmk_firmware`
|
||||||
2. Set the number of RGB diodes in `/keyboards/redox/keymaps/default/config.h`
|
2. Set the number of RGB diodes in `/keyboards/redox/keymaps/default/config.h`
|
||||||
3. Made my own keyboard layout over: https://config.qmk.fm/#/redox/rev1/LAYOUT
|
3. Made my own keyboard layout over: https://config.qmk.fm/#/redox/rev1/LAYOUT
|
||||||
4. Burn it `make redox/rev1:default:avrdude`
|
4. Burn it `make redox/rev1:default:avrdude`
|
||||||
- Of course I've struggled a little bit with this part. I've ended up with running this command with `sudo` as I wasn't able to set some stuff described here: https://docs.qmk.fm/#/faq_build?id=can39t-program-on-linux
|
- Of course, I've struggled a little bit with this part. I've ended up running this command with `sudo` as I wasn't able to set some stuff described here: https://docs.qmk.fm/#/faq_build?id=can39t-program-on-linux
|
||||||
|
|
||||||
In case you want to check out my configuration you can [download it here](/files/redox_keyboard_layout.json 'Keyboard layout mappings for QMK configuration tool') and upload it into the configurator. I've added some multimedia keys in a third layout and much more.
|
In case you want to check out my configuration you can [download it here](/files/redox_keyboard_layout.json 'Keyboard layout mappings for QMK configuration tool') and upload it into the configurator. I've added some multimedia keys in a third layout and much more.
|
||||||
|
|
||||||
@ -167,9 +167,9 @@ And that's it. You have built yourself a keyboard.
|
|||||||
|
|
||||||
Well, I just made a big change in my experience with writing. I was learning to write with 10 fingers and if that wasn't the biggest change I've made. I've decided that if I am going to learn to write properly I'll do it even better. I've learned to use the **Colemak keyboard layout**. To enhance it to the best experience possible I've built myself an **orthodox split keyboard** and I must say: **_WORTH IT!_**
|
Well, I just made a big change in my experience with writing. I was learning to write with 10 fingers and if that wasn't the biggest change I've made. I've decided that if I am going to learn to write properly I'll do it even better. I've learned to use the **Colemak keyboard layout**. To enhance it to the best experience possible I've built myself an **orthodox split keyboard** and I must say: **_WORTH IT!_**
|
||||||
|
|
||||||
So what are the little things that come with switching to orthodox keyboard, you may ask. Well it depends on your habits. Mine were certainly very bad as I didn't know how to write with 10 fingers. Only 8 in my case. Also I was used to type H and Y keys with my left hand. But that was not the biggest problem. Most errors I've made was by trying to hit `C` key. I was used to hitting it with my pointer finger which I think is not only my issue. With the classic keyboard design, hitting the `C` key with middle finger seems like a torture. After one month I am now able to properly hit any key with the correct finger. I just still do many mistakes because of the layout change.
|
So what are the little things that come with switching to an orthodox keyboard, you may ask? Well, it depends on your habits. Mine was certainly very bad as I didn't know how to write with 10 fingers. Only 8 in my case. Also, I was used to typing H and Y keys with my left hand. But that was not the biggest problem. Most errors I've made was by trying to hit the `C` key. I was used to hitting it with my pointer finger which I think is not only my issue. With the classic keyboard design, hitting the `C` key with the middle finger seems like torture. After one month I am now able to properly hit any key with the correct finger. I just still do many mistakes because of the layout change.
|
||||||
|
|
||||||
I've chosen very light switches because I wanted them to be less noisy as I work in a shared office and also my ol' _Cherry browns_ seem a little too hard to me. I have to say this change was very hard to get used to. First 3 days I was accidentally pushing `oooooooooooo` key while trying to concentrate on which key I should press while learning new shortcuts. Simply put, I cannot rest my fingers on keyboard like I've used to. But I think that they are not that bad after I got used to them. Sometimes I accidentally press `Backspace` just before hitting `Enter`. Therefore I'd definitely recommend getting heavier switches for function keys. If I was to make another keyboard, which I am definitely going to make, I will choose something in between. When I try to type on my old keyboard I feel like I have to do push ups with my fingers. But I know it is just because I got used to these light ones.
|
I've chosen very light switches because I wanted them to be less noisy as I work in a shared office and also my ol' _Cherry browns_ seem a little too hard for me. I have to say this change was very hard to get used to. First 3 days I was accidentally pushing `oooooooooooo` key while trying to concentrate on which key I should press while learning new shortcuts. Simply put, I cannot rest my fingers on the keyboard as I've used to. But I think that they are not that bad after I got used to them. Sometimes I accidentally press `Backspace` just before hitting `Enter`. Therefore I'd definitely recommend getting heavier switches for function keys. If I was to make another keyboard, which I am definitely going to make, I will choose something in between. When I try to type on my old keyboard I feel like I have to do push-ups with my fingers. But I know it is just because I got used to these light ones.
|
||||||
|
|
||||||
![Workspace setup at work](/images/uploads/2020-03-23_20-24-18-981.jpg 'Workspace setup at work')
|
![Workspace setup at work](/images/uploads/2020-03-23_20-24-18-981.jpg 'Workspace setup at work')
|
||||||
|
|
||||||
|
@ -2,22 +2,22 @@
|
|||||||
layout: blog
|
layout: blog
|
||||||
title: How to deal with technical debt
|
title: How to deal with technical debt
|
||||||
published: true
|
published: true
|
||||||
date: 2020-11-08T15:57:18.797Z # TODO executable line for generating date
|
date: 2020-11-08T15:57:18.797Z
|
||||||
tags:
|
tags:
|
||||||
- Development
|
- Development
|
||||||
notes: Dont forget the todos
|
notes: Dont forget the todos
|
||||||
---
|
---
|
||||||
|
|
||||||
Technical debt is a massive problem which costs a lot of time for everyone working on the team.
|
Technical debt is a massive problem that costs a lot of time for everyone working on the team.
|
||||||
It should be part of the development cycle to eliminate it.
|
It should be part of the development cycle to eliminate it.
|
||||||
**Manage a secured time** in a development process to increase development experience.
|
**Manage a secured time** in a development process to increase development experience.
|
||||||
|
|
||||||
By planning **regular tasks** like:
|
By planning **regular tasks** like:
|
||||||
|
|
||||||
- Upgrading dependencies, gathering information about migrations and creating tasks for those which require attention.
|
- Upgrading dependencies, gathering information about migrations, and creating tasks for those which require attention.
|
||||||
- Solving _action points_ discussed on retrospective.
|
- Solving _action points_ discussed on retrospective.
|
||||||
- Finding and creating tasks for dealing with technical debt.
|
- Finding and creating tasks for dealing with technical debt.
|
||||||
|
|
||||||
Assign a certian amount of story points for each sprint to those tasks which have been accumulated and proritized.
|
Assign a certain amount of story points for each sprint to those tasks which have been accumulated and prioritized.
|
||||||
|
|
||||||
> _Action points_ are tasks agreed upon on **retrospectives**. These are the _points_ which team has agreed on. They should be solved in the upcoming sprint to make developer experience better for whole team.
|
> _Action points_ are tasks agreed upon on **retrospectives**. These are the _points_ which the team has agreed on. They should be solved in the upcoming sprint to make the developer experience better for the whole team.
|
||||||
|
41
_posts/blog/2020-11-20-ive-moved-my-site-to-netlify.md
Normal file
41
_posts/blog/2020-11-20-ive-moved-my-site-to-netlify.md
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
---
|
||||||
|
layout: blog
|
||||||
|
title: I've moved my site to Netlify
|
||||||
|
published: true
|
||||||
|
date: 2020-11-20T20:35:05.230Z
|
||||||
|
tags:
|
||||||
|
- News
|
||||||
|
- Development
|
||||||
|
- Serverless
|
||||||
|
---
|
||||||
|
## Prelude
|
||||||
|
|
||||||
|
So I've been trying to set access to my CMS for a long time now. The problem was that in order to have CMS accessible through my domain, it **requires an _OAuth_ server**.
|
||||||
|
I've figured out that creating a custom **serverless function** which will handle the authentication with _GitHub_ would be sufficient.
|
||||||
|
So I've took some inspiration from the 2 repositories linked in [_Netlify CMS_ documentation](https://www.netlifycms.org/docs/external-oauth-clients/):
|
||||||
|
|
||||||
|
- [netlify-serverless-oauth2-backend](https://github.com/marksteele/netlify-serverless-oauth2-backend)
|
||||||
|
- [netlify-cms-github-oauth-provider](https://github.com/vencax/netlify-cms-github-oauth-provider)
|
||||||
|
|
||||||
|
The reason because I link both of these was that I've used the _almighty AWS Amplify_ CLI to create an API for me, which has bootstrapped an [_express_](http://expressjs.com/) application for me. This turned out to be way easier then to make 4 independent _functions_ as _Amplify_ is not providing a different way of creating simple shared repository of multiple functions like [serverless-framework](https://www.serverless.com/) does.
|
||||||
|
|
||||||
|
At one point as I was struggling with the _Amplify_ CLI it **managed to delete** whole API once as I was trying to synchronize my changes with the cloud. But somewhere in the development process of the _Amplify framework_ they made some changes which had made my previously used backend environments unusable. I wasn't able to find any migration information about these changes or anything. I'd found some GitHub issues about similar problems which haven't been resolved in any user friendly manners. So I've decided to just **re-create these environments**. I was lucky that I haven't had anything important published in these. Also my IDE had saved me and I was able to **restore deleted files from cache**.
|
||||||
|
|
||||||
|
## Turning point
|
||||||
|
|
||||||
|
After several attempts to publish the API on the AWS I figured out that to be able to use this API I have to configure a custom domain for it because _AWS API Gateway_ appends `/${stage}` to every URL that it is published. This wouldn't be so bad for any API but I was trying to create a **OAuth authentication** for _Netlify CMS_ which required the [`base_name` to be equal to the `origin`](https://github.com/netlify/netlify-cms/blob/aded9d7c24f40f6fa6a159ea764c1e4fccbe82c3/packages/netlify-cms-lib-auth/src/netlify-auth.js#L44) of the API. I was trying to configure custom domain name for this API then. Thinking that _Amplify_ will be able to help me, but this isn't a concern for its use case yet. So I've managed to create a certificate for the domain first. Waited half an hour for validation. And then finally I've got to the point that to be able to configure that custom domain name for this API I will have to configure _AWS Route58_, which is their DNS configuration service, to manage my entire domain which I haven't set up yet as I didn't think it would be necessary. My site has been working correctly just with `CNAME` configuration just right.
|
||||||
|
|
||||||
|
That was my the moment I've decided to **quit AWS completely**. This was after 2 days configuring and debugging a very simple think such as creating a simple API with 4 routes.
|
||||||
|
|
||||||
|
## Alternatives
|
||||||
|
|
||||||
|
I've done some research and was looking between 2 main contenders to host my precious website:
|
||||||
|
|
||||||
|
- [Netlify](https://www.netlify.com/)
|
||||||
|
- [Vercel](https://vercel.com/)
|
||||||
|
|
||||||
|
I haven't found a big decider feature in any of these so I just went with the one I already had an account set up - _Netlify_.
|
||||||
|
I was able to **configure whole deployment** of my website **in 8 minutes**.
|
||||||
|
The instructions where so clear and simple that I've also **transfered my DNS nameserver** too. I didn't have to search in 10 different services and documentations. I've just went with the flow. Didn't had to change a single line of code. I've just removed the `amplify` folder and I don't want to see any of the AWS docs ever again.
|
||||||
|
|
||||||
|
It got me so pumped that I've immediately logged in to the CMS (finally) through my own domain and written this article.
|
160
_posts/blog/2020-12-09-guide-on-error-handling.md
Normal file
160
_posts/blog/2020-12-09-guide-on-error-handling.md
Normal file
@ -0,0 +1,160 @@
|
|||||||
|
---
|
||||||
|
layout: blog
|
||||||
|
title: Guide on error handling
|
||||||
|
published: true
|
||||||
|
date: 2020-12-09T14:44:11.948Z
|
||||||
|
tags:
|
||||||
|
- Development
|
||||||
|
- Guide
|
||||||
|
---
|
||||||
|
Having good _error handling_ practice is very important when building complex applications.
|
||||||
|
Applications which consist of multiple applications such as web applications,
|
||||||
|
where you have multiple parts like _client_, _server_ and _database_ create a system where
|
||||||
|
errors can happen in any individual parts or in communication between them.
|
||||||
|
|
||||||
|
Let me show you some examples of what kind of errors there might happen and how to treat them.
|
||||||
|
|
||||||
|
## Common scenarios
|
||||||
|
|
||||||
|
Don't pay attention to the coding style here.
|
||||||
|
There might be a different kind of libraries and conventions used in applications.
|
||||||
|
Code samples are written just for the demonstration of the various scenarios and what should happen in those scenarios.
|
||||||
|
Please read through the comments as they explain how errors should be treated.
|
||||||
|
|
||||||
|
### Back-end application - Single run script or a CRON job
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
try {
|
||||||
|
// This can be any type of action that might fail
|
||||||
|
Database.connect().insert({ value: 'Some information' })
|
||||||
|
} catch (err) {
|
||||||
|
// It's important to **log these** errors with highest priority (error)
|
||||||
|
logger.error('Error happened while trying to insert some information', err) // Error context is passed here
|
||||||
|
|
||||||
|
// Should the script continue?
|
||||||
|
return
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
It is necessary to pass the error along with context information, that will help to trace and resolve the issue.
|
||||||
|
|
||||||
|
### Back-end application - Responding to client requests
|
||||||
|
|
||||||
|
This is usually how web applications are built and the most common scenario where errors should be properly handled as it might be a security threat.
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
app.post('/message', (req, res) => {
|
||||||
|
const { message, author } = req
|
||||||
|
try {
|
||||||
|
Database.connect().insert({ message, authorId: author.id })
|
||||||
|
} catch (err) {
|
||||||
|
if (err instanceof ValidationError) {
|
||||||
|
// Validation errors are expected to happen often.
|
||||||
|
// They are caused by a bad input from the user.
|
||||||
|
// There is no need to log these errors as they don't cause a system crash.
|
||||||
|
|
||||||
|
// Client should be informed on the matter of what went wrong with the request.
|
||||||
|
res.status(400).json({
|
||||||
|
message: `Invalid input. ${err.message}`
|
||||||
|
})
|
||||||
|
} else if (err instanceof RecoverableError) {
|
||||||
|
// As a `RecovarableError` we can think of an error that most usually doesn't happen
|
||||||
|
// but can and we have a way to continue the rest of the process and handle the error recovery later.
|
||||||
|
// As an example we can imagine a case of sending an email to users with some information.
|
||||||
|
logger.error('Error while sending mail', err, { message, author })
|
||||||
|
|
||||||
|
// Sending an email is not a crucial part of the functionality and can be done later.
|
||||||
|
// So we continue the functionality but we log the error so we know that we have to handle it.
|
||||||
|
res.status(200).json(data)
|
||||||
|
} else {
|
||||||
|
// This is an example of an **unexpected** error.
|
||||||
|
// It doesn't only apply to a `Database`. You can replace the `Database` with any other 3rd party system.
|
||||||
|
// These type of errors can be programmers fault for not handling certain scenarios correctly,
|
||||||
|
// but also be caused by unexpected events happening in the system
|
||||||
|
// (ex. Database server is down, usage of the wrong ID of relations in SQL queries)
|
||||||
|
|
||||||
|
// In this case we want to `log` this error with full context,
|
||||||
|
// so it can be found and fixed if it is a programmer's fault.
|
||||||
|
logger.error('Unexpected error happened', err, { message, author })
|
||||||
|
|
||||||
|
// Client should be informed of such an error but without the context, as it might reveal proprietary information about the system
|
||||||
|
res.status(500).json({
|
||||||
|
message: 'Unexpected error happened'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
It is very important to **keep all proprietary information** about the system **secure and private** only to developers and system administrators.
|
||||||
|
It is a **security threat** and it might be abused by malicious hackers when any of the information gets leaked.
|
||||||
|
It doesn't matter if the information is shown to the users or not, while it's being sent to the client it can be discovered. I
|
||||||
|
|
||||||
|
However, if there is an additional error handling functionality in place which
|
||||||
|
is able to filter out the error context in the `production` environment,
|
||||||
|
it might be a good practice to include the error context in the `development` environment,
|
||||||
|
as it will speed up the error discoverability.
|
||||||
|
|
||||||
|
To implement such a feature I'd recommend splitting `message` types sent to the client,
|
||||||
|
so there isn't a chance that someone would accidentally send proprietary information to the client.
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
function sendError(body) {
|
||||||
|
if (process.env === 'production') {
|
||||||
|
return omit(body, 'errorContext')
|
||||||
|
}
|
||||||
|
return body
|
||||||
|
}
|
||||||
|
|
||||||
|
res.status(500).json(sendError({
|
||||||
|
message: 'Unexpected error happened',
|
||||||
|
errorContext: {req, message: `Error while submitting ${req.path}`, err}
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
### Front-end application - Handle an error from back-end
|
||||||
|
|
||||||
|
When an error happens on the back-end we should show this error to the client so the user knows that his action was not successfully fulfilled.
|
||||||
|
|
||||||
|
If the back-end handles errors correctly and sends the client an appropriate message, the client should be able to just show the informative description of the error that occurred.
|
||||||
|
|
||||||
|
#### Translating errors
|
||||||
|
|
||||||
|
If your application is built with any **internationalization** framework or with a translation system in general,
|
||||||
|
there has to be some kind of mapping from error sent from the back-end to the translated message.
|
||||||
|
|
||||||
|
Simple mapping could be done by having a table of error codes for any application error that might happen.
|
||||||
|
These codes don't have to be strictly numeric. They can consist of some rules like having separators to distinguish
|
||||||
|
services or parts that fail and which way. Examples `RESOURCE-404`, `POST-404`.
|
||||||
|
It's a good practice to have always a default message for unexpected errors which often do happen.
|
||||||
|
|
||||||
|
### Front-end application - Network Error
|
||||||
|
|
||||||
|
These types of errors are least expected by developers but they happen regularly.
|
||||||
|
Users usually lose connection when they browse while traveling or are connected to an unreliable mobile connection.
|
||||||
|
It should always be anticipated that these errors can happen and the application should recover
|
||||||
|
from the failure and allowed to retry their action.
|
||||||
|
|
||||||
|
### Front-end application - unexpected error in application code
|
||||||
|
|
||||||
|
Errors which happen only on front-end are often a coding error.
|
||||||
|
Most common examples would be not covering all possible cases of application logic or accessing properties
|
||||||
|
that are undefined because of the unexpected shape of response data.
|
||||||
|
While back-end applications can recover from their errors by restarting the process,
|
||||||
|
it doesn't apply to client applications where these types of **errors might cause a crash** or a **freeze** of an application.
|
||||||
|
Some frameworks allow to **recover from these crashes** by implementing an **error boundaries**.
|
||||||
|
See [_React_ Error Boundaries for example](https://reactjs.org/docs/error-boundaries.html).
|
||||||
|
I can only highly recommend using such a type of recovery.
|
||||||
|
|
||||||
|
If you use an external error monitoring tool like [Sentry](https://sentry.io/welcome/) or [bugsnag](https://www.bugsnag.com/), don't forget to log these errors from the error boundary.
|
||||||
|
|
||||||
|
## Rules
|
||||||
|
|
||||||
|
To summarize this, we can create a list of rules:
|
||||||
|
|
||||||
|
- Error messages have to be informative for the client, but they **can't reveal private and proprietary information** about the system architecture
|
||||||
|
- Errors should be logged only when they require additional action
|
||||||
|
- Errors that are recoverable should not crash the system
|
||||||
|
- Unexpected errors should turn into expected errors and be handled properly
|
||||||
|
- Failures between connections of the systems should be anticipated
|
||||||
|
- Client applications should be always able to **recover from unexpected errors** just as from expected ones
|
96
_posts/blog/2020-12-18-logging-recommendations.md
Normal file
96
_posts/blog/2020-12-18-logging-recommendations.md
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
---
|
||||||
|
layout: blog
|
||||||
|
title: Logging recommendations
|
||||||
|
published: true
|
||||||
|
date: 2020-12-18T14:39:53.533Z
|
||||||
|
tags:
|
||||||
|
- Development
|
||||||
|
- Guide
|
||||||
|
---
|
||||||
|
## Back-end
|
||||||
|
|
||||||
|
### 1. Use a logger
|
||||||
|
|
||||||
|
**Do not** use `console` directly. Programs should be able to define logging strategies dependant on the environment.
|
||||||
|
We strongly recommend using a logging library such as [Winston](https://github.com/winstonjs/winston) (commonly used in _node.js_ programs).
|
||||||
|
|
||||||
|
Libraries should provide an easy way to choose a _transport_ which will be used as on output for logs.
|
||||||
|
Examples of transports:
|
||||||
|
|
||||||
|
- File
|
||||||
|
- Console
|
||||||
|
- 3rd party monitoring tools (e.g: [loggly](https://www.loggly.com/))
|
||||||
|
|
||||||
|
### 2. Log levels
|
||||||
|
|
||||||
|
You can set up as many log levels as needed.
|
||||||
|
_npm_ uses these 7:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
error: 0,
|
||||||
|
warn: 1,
|
||||||
|
info: 2,
|
||||||
|
http: 3,
|
||||||
|
verbose: 4,
|
||||||
|
debug: 5,
|
||||||
|
silly: 6
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
These are sorted by priority and should be used appropriately.
|
||||||
|
What is logged depends on the environment(dev, test, prod...) in which the program operates.
|
||||||
|
_In the production environment, `debug` logs won't be displayed since they would cause a lot of unnecessary noise._
|
||||||
|
_Verbose logs might be useful for staging environments where you want to see more information about what is happening in the system._
|
||||||
|
|
||||||
|
### 3. What to log
|
||||||
|
|
||||||
|
It is very important to log all the information required for developers and DevOps to retrieve as much valuable information from the logs as possible.
|
||||||
|
|
||||||
|
Messages are usually generated in a way where developers don't have to add things like timestamps, log levels, etc., and repeat themselves.
|
||||||
|
Timestamps and log levels are attached to the messages automatically.
|
||||||
|
|
||||||
|
#### Errors
|
||||||
|
|
||||||
|
Not every error should be logged.
|
||||||
|
Validation errors and expected errors such as handled errors
|
||||||
|
are common and they're expected to happen frequently, so they shouldn't interrupt the system in any way whatsoever.
|
||||||
|
Therefore they should not be seen in logs. They can be shown in the access logs.
|
||||||
|
|
||||||
|
Unexpected errors should be logged with the highest priority (error). These errors should be monitored, prevented, and handled.
|
||||||
|
|
||||||
|
#### System state changes
|
||||||
|
|
||||||
|
Back-end apps strive to be stateless but they also do have some state like:
|
||||||
|
|
||||||
|
- served endpoint, port
|
||||||
|
- database connection
|
||||||
|
- 3rd party integrations
|
||||||
|
|
||||||
|
Changes in the system with valuable information should be logged with the `info` level. They serve as a great source of information about the system prior to the failure.
|
||||||
|
|
||||||
|
#### Debug
|
||||||
|
|
||||||
|
Don't be hesitant to use `debug` logs. They can always be turned off or turned on back again while debugging.
|
||||||
|
Most of the time developers tend to use `console.log` and then remove it before committing.
|
||||||
|
I'd encourage you to use `debug` level and leave it there.
|
||||||
|
It can be a big help in the future which can point you to the part of the code which is responsible for the manipulation of the data.
|
||||||
|
|
||||||
|
### 4. Don't log sensitive information
|
||||||
|
|
||||||
|
**Never, ever log credentials, passwords, or any sensitive information.**
|
||||||
|
|
||||||
|
## Front-end
|
||||||
|
|
||||||
|
Front-end logging is fundamentally different from the back-end.
|
||||||
|
There is a new instance of the program for every opened window and it is only opened for 1 particular client.
|
||||||
|
Developers should **not** expose the functionality to users.
|
||||||
|
|
||||||
|
There is an _npm package_ [debug](https://www.npmjs.com/package/debug) that
|
||||||
|
enables developers to write debug logs that persist in the codebase.
|
||||||
|
To reveal the logs in the console, they have to be enabled.
|
||||||
|
|
||||||
|
There are 3rd party **error monitoring** services, that can help us collect information from errors that occur in different parts of the application.
|
||||||
|
|
||||||
|
- [bugsnag](https://www.bugsnag.com/)
|
||||||
|
- [Sentry](https://sentry.io/welcome/)
|
@ -0,0 +1,17 @@
|
|||||||
|
---
|
||||||
|
layout: blog
|
||||||
|
title: Podcast episode about Agile development
|
||||||
|
published: true
|
||||||
|
date: 2021-02-16T09:09:57.102Z
|
||||||
|
tags:
|
||||||
|
- News
|
||||||
|
- Podcasts
|
||||||
|
- Development
|
||||||
|
---
|
||||||
|
Last week I've been invited as a guest in [Sudolabs Products podcasts](https://open.spotify.com/show/2sAEYvBrVtH74BZP8VGtx2). I've been interviewed by the host and my colleague Ján Koscelanský on my experience with **building and leading** the team behind [The Expert](https://theexpert.com). We were also talking about implementing *Continous Integration* and *End to End* testing with [Cypress framework](https://www.cypress.io/).
|
||||||
|
|
||||||
|
I have to admit, it was a wonderful experience and I've enjoyed it. I'd like to do it again in the future.
|
||||||
|
|
||||||
|
The episode was **recorded in Slovak** language. You can **listen to the podcast episode here**:
|
||||||
|
|
||||||
|
<iframe src="https://open.spotify.com/embed-podcast/episode/0NE6Gakn6wUP6oj7Rq4viR" width="100%" height="232" frameborder="0" allowtransparency="true" allow="encrypted-media"></iframe>
|
@ -12,10 +12,15 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { onMount } from 'svelte'
|
||||||
import ArticleFooter from '../../components/blog/article-footer.svelte'
|
import ArticleFooter from '../../components/blog/article-footer.svelte'
|
||||||
import '../../../static/prism.js'
|
import Prism from '../../../static/prism.js'
|
||||||
|
|
||||||
export let post
|
export let post
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
Prism.highlightAll()
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
Loading…
Reference in New Issue
Block a user