Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Task/update panduan web development #7

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Bagian ini berisi rangkuman dan referensi dasar dasar pemrograman yang wajib dip

- [Panduan SCRUM](https://github.com/medigoid/tech-handbook/blob/develop/scrum.md)

Bagian ini berisi tentang proses SCRUM yang berjalan di Klinik Pintar Indonesia, dan penerapannya di sistem kolaborasi yang digunakan
Bagian ini berisi tentang proses SCRUM yang berjalan di Medigo Indonesia, dan penerapannya di sistem kolaborasi yang digunakan ( Trello )
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ini harusnya pake yang Klinik Pintar

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dan ga pake trello @shani-asad


- [Kolaborasi & Review menggunakan _Pull Request_](https://github.com/medigoid/tech-handbook/blob/develop/pull-request-workflow.md)

Expand Down
112 changes: 110 additions & 2 deletions programming-concepts.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,122 @@ Konsep *Clean Code* mempunyai beberapa penafsiran dan karakteristik, di antarany

> "Clean Code is a code that is written by someone who cares" - **Michael Feathers**

Bacaan tambahan :
---

### Panduan Clean Code
Kenapa kita perlu mempelajari clean code? Karena saat ini hampir seluruh aspek kehidupan manusia dipengaruhi oleh *software*. Penulisan *software* yang buruk dapat menyebabkan masalah besar, bahkan sampai bisa membahayakan nyawa manusia.
Maka dari itu kita sebagai *engineer* perlu untuk bisa menuliskan *software* dengan baik.
Salah satu panduan penulisan *software* yang paling populer ditulis oleh Robert C. Martin dalam bukunya yang berjudul *Clean Code*.

Di bawah ini adalah panduan untuk membuat kode baik berdasarkan Clean Code karya Robert Cecil Martin a.k.a Uncle Bob

---
<br/>

### 1. Long code is not good code
Code yang terlalu panjang itu tidak baik. Code yang terlalu panjang akan menyulitkan pembaca di kemudian hari, baik itu orang lain maupun penulisnya sendiri. Hal ini akan menyulitkan ketika terdapat bug yang berkaitan dengan code tersebut, atau ketika code tersebut perlu di-*refactor*.

Tidak apa menulis code yang panjang di awal, tapi setelah itu kita harus langsung memecah code tersebut ke dalam beberapa *function* atau bahkan *class*.

### 2. Refactoring a function
Katakanlah kita punya sebuah function yang sangat panjang, bagaimana cara me-*refactor*-nya?

Jika dalam sebuah function yang panjang kita menemukan ada beberapa baris code yang dapat dikelompokkan, kita bisa memindahkan code tersebut ke dalam sebuah function baru.

Contohnya kita punya function seperti di bawah: <br>
Code A
```PHP
function printOwing() {
$this->printBanner();

// Print details.
print("name: " . $this->name);
print("amount " . $this->getOutstanding());
}
```

Kita bisa me-*refactornya*-nya menjadi <br>
Code B
```PHP
function printOwing() {
$this->printBanner();
$this->printDetails($this->getOutstanding());
}

function printDetails($outstanding) {
print("name: " . $this->name);
print("amount " . $outstanding);
}
```
##### source: https://refactoring.guru/extract-method

Informasi ebih lanjut tentang *refactoring* dapat dilihat di [Refactoring Guru](https://refactoring.guru/)
### 3. Polite code
Yang dimaksud dengan *polite code* disini adalah ketika sebuah potongan code mengizinkan pembacanya untuk melakukan *early exit*.

Ketika seseorang membaca sebuah code dan di dalam code tersebut terdapat *function call* dengan nama function yang tidak deskriptif, misalnya `retrieve()` dan function ini belum di-*refactor*, maka pembaca tidak bisa *exit* atau berhenti sampai disitu saja, dia harus melihat isi dari function tersebut. Jika ternyata function tersebut belum di-*refactor* dengan baik, katakanlah function tersebut terdiri dari 150 baris, maka pembaca harus memahami keseluruhan dari 150 baris tersebut untuk memahami apa yang dilakukan oleh si function. Ini memakan banyak waktu dan mencegah pembaca untuk melakukan *early exit*.

Jika dari awal *function call* pada code yang dibaca oleh si pembaca memiliki nama yang deskriptif, misalnya `getDoctorsByPolyclinicId()` dan function ini sudah di-*refactor* dengan baik, pembaca tidak perlu membaca isi dari function tersebut untuk memahami apa yang dilakukannya. Kalaupun pembaca ingin melihat isi dari function tersebut, maka dia akan mendapati isinya mudah dibaca karena setiap actions di dalamnya sudah terpecah menjadi beberapa *function calls* dan ini membuat pembaca mudah memahami isi dari function tersebut dan mengizinkan pembaca untuk melakukan *early exit*.

### 4. Shrunk code - the rules of functions
```
THE RULES OF FUNCTIONS:

The first rule:
- They should be small

The second rule:
- They should be smaller than that
```
Seberapa kecil seharusnya sebuah function ditulis?
Sebenarnya tidak ada aturan baku tentang ukuran sebuah function, namun pada dasarnya kita ingin sebuah fungsi hanya melakukan satu hal.\
Sekarang pertanyaannya adalah apa definisi dari *satu hal*?
Uncle Bob mengatakan:
```
A function does one thing until if you cannot meaningfully extract another function from it.
```
Supaya function yang kita tulis hanya melakukan satu hal kita harus memecahnya terus menerus sampai kita tidah bisa memecahnya lagi.

### 5. Rules for arguments
Sebaiknya kita tidak membuat function yang menerima *boolean* sebagai argumen, karena di dalam function tersebut pasti akan ada *if statement*. Lebih baik pisah function tersebut menjadi 2 function berbeda.
### 6. Avoid switch statements
Hindari penggunaan *switch statement* karena akan menyebabkan code menjadi tidak *maintainable*.
Katakanlah kita membuat code untuk menghandle bentuk, segitiga, lingkaran, persegi, dll.
Kita akan perlu *switch statement* untuk merender bentuk, menghapus bentuk, memutar bentuk, dll. Lalu katakan kita perlu menambahkan bentuk baru, saat inilah masalah muncul, karena sekarang kita harus mengupdate seluruh *switch statements* yang sudah kita buat.

Solusi untuk masalah ini adalah [*polymorphism*](#polymorphism). Kita bisa membuat *base class* bernama *shapes* untuk bentuk dan membuat *subclasses* untuk setiap bentuk yang kita inginkan, lalu mengaplikasikan functions yang sesuai pada *subclasses* tersebut.

### 7. Command and query separation
Sebuah function dikatakan memiliki side effect jika dia merubah state dari sistem. Misalkan function`open()` untuk membuka file, atau `malloc()` untuk mengalokasikan blok memori.

Sebuah function yang me-*return* *void* pasti punya side effect, maka dari itu function yang me-*return* sebuah value, sehrusnya tidak memiliki side effect. Ini adalah konvensi yang disebut dengan *command and query separation*. *Command* merubah state dari sistem maka dari itu dia me-*return* *void*, *query* me-*return* *void* dan berdasarkan konvensi seharusnya tidak merubah state dari sistem.

Pemisahan ini memudahkan kita untuk melacak semua penggunaan *command*. Setiap *command* memiliki pasangan, misalnya `open()` dan `close()`. Setiap kita memanggil `open()`, kita harus memanggil `close()`. Jika terlalu banyak user yang membuka file dan tidak ditutup, sistem bisa mengalami *crash*. Melakukan *command and query separation* dapat membantu menghindari hal ini.

### 8. Prefer exeptions to returning error codes
Ketika kita men-*throw exeption*, *code execution* akan berpindah jalur dari "*happy-path*" ke "*error-path*", ini memudahkan kita dalam menghandle error.

### 9. Rule for try block
Ketika kita menggunakan *try block* dalam sebuah function, satu-satunya yang boleh menjadi isi dari function tersebut adalah *try block*. Jangan menulis code sebelum atau sesudah *try block*, jangan menulis terlalu banyak code di dalam *try block*, dan jangan menulis *nested try block*. Lebih baik jika isi dari sebuah *try block* hanyalah sebuah function call. Sebuah function yang menggunakan *try block* hanya boleh berisi *try*, *catch*, dan *finally*.

### 10. DRY principle (Don't Repeat Yourself)
Jangan menggunakan potongan code yang sama berulang-ulang di berbagai tempat. Ketika kita memiliki potongan code yang perlu digunakan berkali-kali, jadikan potongan code tersebut sebagai sebuah function dan panggil function tersebut dimana dibutuhkan.

### 11. Proper use of comments
Comment diperlukan untuk menjelaskan code yang tidak bisa menjelaskan dirinya sendiri. Pada dasarnya kita harus membuat code kita sangat jelas sampai tidak memerlukan comment. Tetapi ketika ada kondisi dimana code itu sendiri tidak cukup jelas, maka kita perlu menambahkan comment.

Tergantung penggunaannya comment bisa jadi baik maupun buruk.

Referensi tambahan :

[Clean Code : A Handbook of Agile Software Craftmanship](https://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882)

[High Quality Code for Better Programmer](https://www.butterfly.com.au/blog/website-development/clean-high-quality-code-a-guide-on-how-to-become-a-better-programmer)

[Clean Code for Javascript](https://github.com/ryanmcdermott/clean-code-javascript)

[Clean Code - Uncle Bob](https://www.youtube.com/watch?v=7EmboKQH8lM&list=PLmmYSbUCWJ4x1GO839azG_BBw8rkh-zOj)


---
### Konsep Readable Code
Expand Down Expand Up @@ -135,7 +243,7 @@ Secara umum, objek dapat berinteraksi satu dengan yang lainnya dalam hubungan me

> **Contoh** : Kelas `Kendaraan` memiliki properti `roda` dan fungsi `aturKecepatan`. Semua kelas yang menjadi *child class* dari `Kendaraan` akan memiliki `roda` dan fungsi `aturKecepatan` secara otomatis.

**Polymorphism**
#### **Polymorphism**

*Polymorphism* bisa dijabarkan atau diartikan sebagai sebuah operasi yang memiliki beberapa jenis implementasi

Expand Down
134 changes: 126 additions & 8 deletions pull-request-workflow.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,21 @@ Dalam proses _Pull Request_ ini terdapat tiga peran utama, yakni:

Pilihan nama *branch* yang dapat digunakan adalah

- **story**/[nomor redmine] [deskripsi]
- **story**/[nomor trello]-[deskripsi]

> Untuk *Story* yang dirasa terlalu besar, pecah ke dalam *Task* yang lebih kecil untuk kemudian di merge ke *branch* `story` sebelum melakukan *Pull Request* ke *branch* `develop`

- **task**/[nomor redmine] [deskripsi]
- **improvement**/[nomor redmine] [deskripsi]
- **bug**/[nomor redmine] [deskripsi]
- **hotfix**/[nomor redmine] [deskripsi]
- **task**/[nomor trello]-[deskripsi]
- **improvement**/[nomor trello]-[deskripsi]
- **bugfix**/[nomor trello]-[deskripsi]
- **hotfix**/[nomor trello]-[deskripsi]

Contoh:

- task/TQ-091-post-schedule-to-medigo-webhook
- improvement/w-165-use-promise-all-to-get-schedules-api
- bugfix/w-150-slot-number-is-undefined
- hotfix/w-199-health-center-config-not-loaded

**Notes**

Expand All @@ -46,11 +53,122 @@ Untuk repository yang tidak akan mengalami banyak pengembangan ( one and done ),

### Konsep Git

- Gunakan pesan *commit* yang relevan dan masukkan *tag* yang sesuai.
- [ADD] deskripsi penambahan berkas yang dilakukan
- [UPDATE] deskripsi *update* yang dilakukan
- Gunakan pesan *commit* yang relevan dan masukkan *tag* yang sesuai.
- [DOCS] deskripsi perubahan pada dokumentasi
- [ADD] deskripsi penambahan fitur yang dilakukan
- [UPDATE] deskripsi *update* yang dilakukan pada fitur yang ada
- [FIX] deskripsi perbaikan yang dilakukan
- [PERF] deskripsi perubahan yang meningkatkan *performance*
- [STYLE] deskripsi perapian code sesuai *standard* yang dilakukan
- [REFACTOR] deskripsi code yang diubah tetapi bukan perbaikan atau penambahan fitur
- [Git Cheatsheet](https://www.git-tower.com/blog/git-cheat-sheet/)
- [Rewrite Commit History](https://git-scm.com/book/id/v2/Git-Tools-Rewriting-History)
- [Squash Published Commits](https://stackoverflow.com/questions/5667884/how-to-squash-commits-in-git-after-they-have-been-pushed)

### Ketentuan *Pull Request*

*Template* yang digunakan untuk membuat *pull request* (dalam format markdown) adalah

#### ISSUE LINK

Berisi tautan *Trello card* yang berkaitan dengan perubahan yang dilakukan.

#### WHAT TO TEST

Apa saja yang perlu dites untuk memastikan fitur baru atau perbaikan fitur berjalan dengan baik.

#### EXPECTATION

Daftar apa saja yang perlu diperiksa yang dijadikan patokan bahwa fitur berjalan sebagaimana mestinya.

#### HOW

Berisi langkah-langkah mengenai bagaimana cara QA mereproduksi *state* fitur agar bisa melakukan *review* *pull request* tanpa kendala seperti setup, inisialisasi database, software yang perlu di-*install*, dll.

#### ADDITIONAL NOTES

Berisi catatan tambahan atau hal-hal pendukung yang perlu diketahui oleh QA dalam melakukan *review*. Biasanya aset atau *file* yang harus di-*download*, ketergantungan *pull request* di repositori ini dengan *pull request* di repositori lain, dll.

---

Contoh:

#### ISSUE LINK

https://trello.com/c/uPka4Ic7

#### WHAT TO TEST

##### GET POSTS API

Send request to endpoint `GET /api/posts` and give query params as following:

| Key | Value |
|-----------------|-----------------|
| `category_slug` | `dinosaur` |
| `page` | `1` |

#### EXPECTATION

- [ ] Returns status code 200 OK
- [ ] Returns object like this

```json
{
"data": [
{
"id": 1,
"title": "What's my favorite dinosaur? I like any dinosaur that wants to worship my problems",
"excerpt": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam ac lectus dolor. Donec enim tortor, cursus interdum facilisis quis, aliquam ac ipsum. Sed malesuada lacinia molestie. In non diam massa. Duis viverra dictum risus, at pretium erat. Morbi a diam faucibus, placerat lectus nec, dapibus lectus. Donec id massa urna.",
"image": "http://localhost:8002/storage/posts/2020-01/iPZcSQJfvroaMobBoYcX.png",
"link": "http://localhost:8002/blog/whats-my-favorite-dinosaur-i-like-any-dinosaur-that-wants-to-worship-my-problems",
"meta_description": "Amtocephale Pamparaptor Daxiatitan Kundurosaurus Carcharodontosaurus Shuosaurus Unaysaurus Shenzhouraptor Lexovisaurus Bradycneme.",
"meta_keywords": "cephale, raptor, saurus, bradycneme, titan",
"created_at": {
"date": "2020-01-20 08:00:10.000000",
"timezone_type": 3,
"timezone": "UTC"
}
}
],
"links": {
"first": "http://localhost:8002/api/posts?page=1",
"last": "http://localhost:8002/api/posts?page=1",
"prev": null,
"next": null
},
"meta": {
"current_page": 1,
"from": 1,
"last_page": 1,
"path": "http://localhost:8002/api/posts",
"per_page": 5,
"to": 1,
"total": 1
}
}
```

#### HOW

1. Install and use PHP 7.1,
2. Install and use MySQL 5.6 or MariaDB,
3. Create a database for this app (name is up to you),
4. Restore the database with attached SQL script,
5. Clone this repo to your local machine,
6. Change directory to the cloned repo,
7. Run `composer install`,
8. Run `php artisan key:generate`,
9. Change `APP_URL` to `http://localhost:8002` in `.env` file,
10. Change DB related variables according to your own database in `.env` file,
11. Run `php artisan serve --port:8002`,
12. Login to http://localhost:8002/admin using `[email protected]` and `secret` as credentials,
13. Go to Categories menu from sidebar,
14. Add new category with Name Dinosaur (don’t change the slug),
15. Edit any post and change the Post Category to Dinosaur,
16. Send request the API endpoint mentioned above using Postman or any other REST client.
17. See if the returned posts are only of Dinosaur category.

#### ADDITIONAL NOTES

SQL script: [download link](https://google.co.id)