# Larasoft's Transparent SOPs

We offer an industry leading transparent look at all our SOPs

![](/files/-MT_1siYuP5bRFWirLOQ)

We're super confident about the quality of our code and the compliance to Community Standards.  We constantly review, update and publicly publish these documents that uphold the Standards that we code to.  We encourage all our clients to critique and offer insight or discussion into everything we do.

We hope you find this documentation an interesting look into the way we work.

If you're already working with us, you can take confidence in knowing your code is being well looked after.

If you're looking for a Laravel Development Agency to work with, then you'll want to do some due diligence on any developer's that are going to work on your project.  Take a look through this documentation which will help you to build a picture of the structure, organisation and professionalism that you'll receive from any Larasoft.io project.  We look forward to discussing how we can help you to design and develop your web or mobile app!


# Getting Started

Laravel Specific Standard Operating Procedures that keep us true to the Community Standards

#### **The Ecosystem**

At the very minimum, you need to know how to use [Git](https://git-scm.com/) and [Composer](https://getcomposer.org/). Though not required, it is better that you have an account on [GitHub.com](https://github.com/) as it is where all the code and its dependencies are hosted.

You MUST be comfortable in using [Command Line Interface (CLI)](https://en.wikipedia.org/wiki/Command-line_interface), specially Unix Shells (sh, ksh, csh, tcsh, bash etc) as it is heavily used for common tasks in working with Laravel.

For local development, you’ll need to have at least [Vagrant](https://www.vagrantup.com/) and [VirtualBox](https://www.virtualbox.org/) installed. This is used by [Homestead](https://laravel.com/docs/5.8/homestead) (a special vagrant box made for running Laravel apps). Although you can use the traditional WAMP/MAMP/XAMPP stack, those are not officially supported, thus you might have hard time down the road.

Pure “Laravel-way” frontend development might be a daunting one as it got has a long chain of technologies. You can either use [Laravel Blade](https://laravel.com/docs/7.x/blade) which is server-side templating or do client-side (browser), which at the very top of the chain is [Mix](https://laravel.com/docs/7.x/mix), a wrapper for [Webpack](https://webpack.js.org/). Webpack has its dependencies managed through [npm](https://www.npmjs.com/), all of which are packages of [NodeJS](https://nodejs.org/en/).

CSS is managed either through [Sass](http://sass-lang.com/) or [LESS](http://lesscss.org/), while JavaScript can be done through Plain JavaScript, [ReactJS](https://reactjs.org/) and the more common frontend framework used with Laravel: [VueJS](https://vuejs.org/%22%20/t%20%22_blank).

For the backend stack, at the very least, you need a web server like [Nginx](http://nginx.org/), a php interpreter like [PHP-FPM](http://php-fpm.org/) and a database like [MySQL](https://www.mysql.com/). Other optional stack components are [Memcached](http://memcached.org/), [Redis](http://redis.io/) and [Beanstalkd](http://kr.github.io/beanstalkd/%22%20/t%20%22_blank).

While you are not required to understand them all at once, it is advantagous that you are at least familiar with these and do some reading about what they are and where they are being used. This will save you tons of confusion when reading the documentation and references in the future.


# How to read this guide

This guide is divided into several sections such as each one tries to group related conventions. For example, all database-related convention is grouped in the same section. Each of the convention have the following keywords, which indicates how important it is to comply with such convention:

* **MUST** This word, or the terms “REQUIRED” or “SHALL”, mean that the definition is an absolute requirement of the specification.
* **MUST NOT** This phrase, or the phrase “SHALL NOT”, mean that the definition is an absolute prohibition of the specification.
* **SHOULD** This word, or the adjective “RECOMMENDED”, mean that there may exist valid reasons in particular circumstances to ignore a particular item, but the full implications must be understood and carefully weighed before choosing a different course.
* **SHOULD NOT** This phrase, or the phrase “NOT RECOMMENDED” mean that there may exist valid reasons in particular circumstances when the particular behavior is acceptable or even useful, but the full implications should be understood and the case carefully weighed before implementing any behavior described with this label.
* **MAY** This word, or the adjective “OPTIONAL”, mean that an item is truly optional.

the above specifications is derived from [RFC 2119](https://www.ietf.org/rfc/rfc2119.txt)


# Environment

### **Local Environment**

There are multiple ways to run Laravel in local environment as outlined below:

* [**Homestead**](https://laravel.com/docs/5.8/homestead) - requires VirtualBox, Vagrant
* [**Valet**](https://laravel.com/docs/5.8/valet) - only runs in MacOS
* [**Laradock**](https://laradock.io/) - requires Docker Engine

You are free to choose which local environment that works for you and your team as long as the following conditions are met:

* Your local environment **MUST** be able to duplicate the production server or close to its specifications such as PHP version, extensions installed and MySQL version
* .env file **MUST NOT** be commited into repository
* You **SHOULD NOT** be connecting to your any production server when you are debugging locally, to prevent accidental corruption of data, unintended API call or similar incident.
* You **SHOULD NOT** be using personally identiable information (PII) of your end-users data or any data that could potentially identify a specific individual such as first/last name, address, medical condition so on and so forth, unless you are explicitly authorized by your company or client to do so.
* You **MUST** update the readme.md file for any special instruction on how to run the app in local environment, so that other developers who will setup the app in their local machine can follow them properly.
* While it is possible to WAMP or XAMP for Laravel, this is un-common practice so you **SHOULD** try to familiarize yourself on how server components works and be comfortable in dealing with them.

### **Staging Environment**

Staging servers is a type of server that is used to test a software, website or service in a production-similar environment before being set live. It is the role of a staging environment or staging site, to serve as a temporary hosting and testing server for any new software or feature.

* It is **RECOMMENDED** to use [**Continous**](https://www.thoughtworks.com/continuous-integration%22%20/t%20%22_blank) [**Integration**](https://www.thoughtworks.com/continuous-integration%22%20/t%20%22_blank) to automatically run your Tests and keep a record of the results. For example [Travis CI](https://travis-ci.org/) or [Jenkins](https://jenkins.io/)

### **Production Environment**

**You MUST regularly rotate your APP\_KEY**

APP\_KEYS are set when you initialized a new Laravel application or executed the following command

php artisan key:generate

*Laravel uses the key for all encrypted cookies, including the session cookie, before handing them off to the user’s browser, and it uses it to decrypt cookies read from the browser. This prevents the client from making changes to their cookies and granting themselves admin privileges or impersonating another user in your application. Encrypted cookies are an important security feature in Laravel*

From [APP\_KEY And You](https://tighten.co/blog/app-key-and-you)


# Configuration

**Environment Variables**

**You MUST put sensitive information into .env files**

Use .env files to store any secure information and retrieve it via **env** function. There should be no instance on which you will put it inside models/controllers and commit it to Git.

Good

// .env

`API_HOST=https://example.com/api`

`API_USERNAME=myuser`

`API_PASSWORD=secret`

// access the value from app/config.php file

`return [`

&#x20;`...`

&#x20;`'api_host' => env('API_HOST', 'https://defaultdomain.com')`

&#x20;`'api_username' => env('API_USER', 'defaultuser')`

&#x20;`'api_password' => env('API_USER', 'defaultpassword')`

&#x20;`...`

`]`

Bad

`define('API_HOST', 'https://defaultdomain.com');`

`define('API_USERNAME', 'defaultuser');`

`define('API_PASSWORD', 'defaultpassword');`

`class DomainController extends Controller`

`{`

&#x20;`public function index()`

&#x20;`{`

&#x20;`$api_username`

&#x20;`}`

**your application key MUST be set. This is the APP\_KEY variable in your .env file. You can generate one via**

`php artisan key:generate`

**Package Configuration**

**Custom or Package configuration filename MUST be in snake\_case**

Good

`config/my_config.php`

Bad

`config/MyConfig.php`

**Config and language files indexes SHOULD be in snake\_case**

Good

// config/myconfig.php

`return [`

&#x20;`'my_api' => [`

&#x20;`'domain' => env('API_DOMAIN'),`

&#x20;`'secret' => env('API_SECRET'),`

&#x20;`],`

Bad

// config/myconfig.php

`return [`

&#x20;`'MyApi' => [`

&#x20;`'DOMAIN' => env('API_DOMAIN'),`

&#x20;`'SECRET' => env('API_SECRET'),`

&#x20;`],`

*The best way to figure out if you have implemented best-practice in configuring your app, is if the codebase could be made open source at any moment without compromising any credentials*


# Naming Conventions

The following is the generally accepted naming conventions being used by Laravel Community:

**Controllers**

**Controller name MUST start with a noun (in singular form) followed by the word “Controller”.**

**Good**

`class ArticleController extends Controller`&#x20;

`{ ...`

**Bad**

`class ArticlesController extends Controller`

`{...`

`class wp_articlesController extends Controller`

`{`

`class Article extends Controller`

`{`

**You SHOULD Use Resource Controllers unless you have any particular reason not to do so**

**Good**

`class DomainController extends Controller`

`{`

&#x20;`public function index(){} // list domains`

&#x20;`public function create(){} // show create form`

&#x20;`public function store(Request $request){ } // handle the form POST`

&#x20;`public function show($id){} // show a single domain`

&#x20;`public function edit($id){} // show edit page`

&#x20;`public function update(Request $request, $id){} // handle show edit page POST`

&#x20;`public function destroy($id){} // delete a domain`

`}`

**Bad**

`class DomainController extends Controller`

`{`

&#x20;`public function list(){} // list domains`

&#x20;`public function create_or_save(){} // show create form then handle save`

&#x20;`public function show_edit($id){} // show a single domain then show edit page`

&#x20;`public function delete($id){} // delete a domain`

`}`

**Models**

**Model names MUST be in singular form with its first letter in uppercase**

**Good**

`class Flight extends Model`

`{`

`...`

**Bad**

`class Flights extends Model`

`{`

`...`

`class flight extends Model`

`{`

`...`

**hasOne or belongsTo relationship methods MUST be in singular form**

**Good**

`class User extends Model`

`{`

&#x20;`public function phone()`

&#x20;`{`

&#x20;`return $this->hasOne('App\Phone');`

&#x20;`}`

`}`

**Bad**

`class User extends Model`

`{`

&#x20;`public function phones()`

&#x20;`{`

&#x20;`return $this->hasOne('App\Phone');`

&#x20;`}`

`}`

**Any other relationships other than above MUST be in plural form**

**Good**

`class Post extends Model`

`{`

&#x20;`public function comments()`

&#x20;`{`

&#x20;`return $this->hasMany('App\Comment');`

&#x20;`}`

`}`

**Bad**

`class Post extends Model`

`{`

&#x20;`public function comment()`

&#x20;`{`

&#x20;`return $this->hasMany('App\Comment');`

&#x20;`}`

`}`

**Model properties should be in snake\_case**

**Good**

`$user->created_at`

**Bad**

`$user->createdAt`

**Methods should be in camelCase**

**Good**

`class User extends Model`

`{`

&#x20;`public function scopePopular($query)`

&#x20;`{`

&#x20;`return $query->where('votes', '>', 100);`

&#x20;`}`

**Bad**

`class User extends Model`

`{`

&#x20;`public function scope_popular($query)`

&#x20;`{`

&#x20;`return $query->where('votes', '>', 100);`

&#x20;`}`

**Functions**

Laravel comes with a lot of useful helper functions, but you can also define your own helper functions, given the following conditions:

**You SHOULD place your custom helper functions by creating a file called helper.php**

**Good**

`project_folder/app/helper.php`

`project_folder/app/Http/helper.php`

**Bad**

`project_folder/functions.php`

**You MUST use Composer’s autoloading capability to load your functions**

**Good**

// file composer.json

`...`

`"autoload": {`

&#x20;`"files": [`

&#x20;`"app/helpers.php"`

&#x20;`],`

`...`

**Bad**

`// file app/Http/Controllers/HomeController.php`

`class HomeController.php`

`{`

&#x20;`function index(){`

&#x20;`require_once(app_path("helpers.php"));`

&#x20;`}`

`}`

**You MUST check if the the function exists before defining it**

**Good**

`if (! function_exists('my_custom_helper')) {`

&#x20;`function my_custom_helper($key, $default = null) {`

&#x20;`// ...`

&#x20;`}`

`}`

**Bad**

`function my_custom_helper($key, $default = null) {`

&#x20;`// ...`

`}`

**Other General guides with functions**

* If the function length exceeds 25 lines, you SHOULD break it down to multiple functions
* Each function SHOULD have a **Unit Test** associated with it

**Routes**

**Routes should be in plural form of the resource it is trying to manipulate and SHOULD be all lower-case**

**Good**

`Route::get('/users', 'UserController@index');`

`Route::resource('photos', 'PhotoController');`

**Bad**

`Route::get('/user', 'UserController@index');`

`Route::get('/UsersList', 'UserController@index');`

`Route::resource('PHOTO', 'PhotoController');`

**Named Routes SHOULD use snake\_case and dot notation**

**Good**

`Route::get('/user', 'UserController@active')->name('users.show_active');`

**Bad**

`Route::get('/user', 'UserController@active')->name('users.show-active');`

`Route::get('/user', 'UserController@active')->name('show-active-users');`

**Variables**

**General rule for variable is it SHOULD be in camelCase**

**Good**

`$articlesWithAuthor`

**Bad**

`$articles_with_author`

**Collection names SHOULD be descriptive and in plural form**

**Good**

`$activeUsers = User::active()->get()`

**Bad**

`$users = User::active()->get()`

`$user = User::active()->get()`

`$User = User::active()->get()`

**Single Object SHOULD be descriptive and in singular form**

**Good**

`$activeUser = User::active()->first()`

**Bad**

`$users = User::active()->first()`

**Views**

**You SHOULD use snake\_case as file name of your Blade templates**

**Good**

`show_filtered.blade.php`

**Bad**

`showFiltered.blade.php`

`show-filtered.blade.php`

**You MUST not make non UI-related operations inside blade templates**

**Good**

// $api\_results is passed by controller

`<ul>`

&#x20;`@foreach($api_results as $result)`

&#x20;`<li>{{ $result->name }}</li>`

&#x20;`@endforeach`

`</ul>`

**Bad**

`@php`

&#x20;`$api_results = json_decode(file_get_contents("https://api.example.com"));`

`@endphp`

`<ul>`

&#x20;`@foreach($api_results as $result)`

&#x20;`<li>{{ $result->name }}</li>`

&#x20;`@endforeach`

`</ul>`


# Database Conventions

**Table and Fields Naming**

**Table names MUST be in plural form and MUST be all lower-case**

Good

`class CreateFlightsTable extends Migration`

`{`

&#x20;`public function up()`

&#x20;`{`

&#x20;`Schema::create('flights', function (Blueprint $table) {`

Bad

`class CreateFlightsTable extends Migration`

`{`

&#x20;`public function up()`

&#x20;`{`

&#x20;`Schema::create('flight', function (Blueprint $table) {`

`class CreateUsersTable extends Migration`

`{`

&#x20;`public function up()`

&#x20;`{`

&#x20;`Schema::create('MyUsers', function (Blueprint $table) {`

**Pivot table names MUST be in singular model names in alphabetical order**

Good

`post_user`

`article_user`

`photo_post`

Bad

`posts_users`

`user_articles`

`post_photos`

**Table column names SHOULD be in snake\_case without the model name**

Good

`username`

`title`

`thumb_url`

Bad

`UserName`

`_title`

`ThumbUrl`

`post_title`

**Foreign keys MUST be singular model name with \_id suffix**

Good

`user_id`

Bad

`userid`

`siteid`

`Memberid`

`TransactionID`

**Primary Keys SHOULD be “id”**

Good

`id`

Bad

`ID`

`pkid`

`guid`

**Database Alterations**

**You MUST not be changing the database schema directly, use Database Migrations instead**

Good

`php artisan migrate`

Bad

* use of PHPMyAdmin
* directly executing ALTER statement in mysql console / cli
* using sql file to change the db

**Migration filenames MUST follow to following pattern**

creation of table

`yyyy_mm_dd_<timestamp>_create_<table name>_table`

Good

`2019_06_06_164210_create_domains_table.php`

Bad

`2019_06_06_164210_domains.php`

**Database Choice**

**Polyglot Persistence**

Is a practice of using different data storage technologies for different kinds of data. Eloquent ORM can support multiple database for a reason, so don’t limit yourself to MySQL.

* It is RECOMMENDED to use [MongoDB](https://github.com/jenssegers/Laravel-MongoDB) for records that have attributes that vary a lot. For example, in an inventory system, an office supplies product might have a different set of fields compared to vehicle and auto supplies.
* It is RECOMMENDED to use [ElasticSearch](https://github.com/elasticquent/Elasticquent%22%20/t%20%22_blank) for high volume data searching and indexing.
* It is RECOMMENDED to use [Neo4J](https://github.com/Vinelab/NeoEloquent) for applications that require complex relationships between models. For example a multi-level networking application, social network site and similar apps.

From this [article](https://martinfowler.com/bliki/PolyglotPersistence.html), here is a sample breakdown of different databases being used by a retailer company

![Sample Company](/files/-MT_4TQ3qbDa0PP_7TxT)


# Design Patterns

**Design Patterns**

**SOLID**

SOLID is five design principles intended to make software designs more understandable, flexible and maintainable.

**Single responsibility principle**

*A class should only have a single responsibility, that is, only changes to one part of the software’s specification should be able to affect the specification of the class.*

**Open–closed principle**

*Software entities … should be open for extension, but closed for modification.*

**Liskov substitution principle**

*Objects in a program should be replaceable with instances of their subtypes without altering the correctness of that program.*

**Interface segregation principle**

*Many client-specific interfaces are better than one general-purpose interface.*

**Dependency inversion principle**

*One should depend upon abstractions, \[not] concretions.*

**Repository Pattern**

The idea with this pattern is to have a generic abstract way for the app to work with the data layer without being bothered what storage technology is used when saving/retrieving the data.

*We suggests to check first this* [*tutorial*](https://medium.com/@jsdecena/refactor-the-simple-tdd-in-laravel-a92dd48f2cdd) *for in-depth understand about this design pattern.*

**When reading/writing data, it is RECOMMENDED to wrap it into Repository Object**


# Testing

**Unit Testing**

**Methods in test classes MUST start with “test” then a camelCased name of the test**

Good

`class ExampleTest extends TestCase`

`{`

&#x20;`public function testBasicTest()`

&#x20;`{`

Bad

`class ExampleTest extends TestCase`

`{`

&#x20;`public function test_basic_test()`

&#x20;`{`

**Integration Tests**

*WIP (work in progress): this will be filled up by collected best practices once we had done enough research about the subject matter.*

**Acceptance Tests**

*WIP (work in progress): this will be filled up by collected best practices once we had done enough research about the subject matter.*

**Scalability**

*WIP (work in progress): this will be filled up by collected best practices once we had done enough research about the subject matter.*

**Scaling Up**

*TODO*

**Scaling Out**

*TODO*

**Microservices**

*WIP (work in progress): this will be filled up by collected best practices once we had done enough research about the subject matter.*


# Frontend Development

**Frontend Development**

Laravel can use a variety of frontend javascript frameworks. It also provides for frontend presets (or ways to scaffold a frontend) which provides a basic starting point using [Bootstrap](https://getbootstrap.com/), [React](https://reactjs.org/), and / or [Vue](https://vuejs.org/).

**Auth Scaffolding**

Starting in laravel 6, the artisan make:auth scaffolding has been moved to the laravel/ui package.

**Generating scaffolding**

You can read more about generating scaffolding on the [docs/frontend](https://laravel.com/docs/7.x/frontend) page.

**Compiling Assets**

Everytime you add a new component to your app.js file, you need run npm run dev to compile the new component into javascript. To develop while automatically reloading your page everytime you change a frontend file, you can run npm run watch. For more information on how to configure laravel mix to compile different types of assets, please checkout the docs on [compiling assets](https://laravel.com/docs/7.x/mix#installation).

**CORS requests**

When developing a Single Page Application with laravel as the backend, you have to setup your middleware to accept [CORS request](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS). Laravel 7 introduced [native support for CORS](https://laravel.com/docs/7.x/routing#cors), but if you are on an earlier version of laravel, you can use [spatie](https://github.com/spatie/laravel-cors)[/](https://github.com/spatie/laravel-cors)[laravel-cors](https://github.com/spatie/laravel-cors) to allow for requests to push through. You can learn about CORS [here](https://httptoolkit.tech/will-it-cors/).

**CSRF Token**

When developing your [SPA](https://flaviocopes.com/single-page-application/), you may still want to secure your application’s forms with Laravel’s default CSRF Tokens. To do so, you’ll need to attach the CSRF token to your form requests. You can do this by adding the value of the X-XSRF-TOKEN header. If you are building the SPA separately from your laravel app, you might want to use api-tokens instead. In Laravel 7, you can use [Laravel Sanctum’s API Token Authentication](https://laravel.com/docs/7.x/sanctum#api-token-authentication) for this.


# Resources and Links

**Resources**

* [How to Hire a Great Laravel Developer](https://www.toptal.com/laravel#hiring-guide)

**People to Follow**

* [Taylor Otwell](https://twitter.com/taylorotwell)
* [Dayle Rees](https://twitter.com/daylerees)
* [Shawn McCool](https://twitter.com/ShawnMcCool)
* [Jeffrey Way](https://twitter.com/jeffrey_way)
* [Chris Fidao](https://twitter.com/fideloper)
* [Phil Sturgeon](https://twitter.com/philsturgeon)
* [Jens Segers](https://twitter.com/jenssegers)
* [Ben Corlett](https://twitter.com/ben_corlett)
* [Matt Stauffer](https://twitter.com/stauffermatt)
* [Graham Campbell](https://twitter.com/grahamjcampbell)

**Mentoring**

* [Laravel Forum](http://laravel.io/forum) - official forum and IRC channels for Laravel.
* [Laravel Recipes](http://laravel-recipes.com/) - useful tips and tutorials.

**PHP PaaS Providers**

* [Forge](https://forge.laravel.com/)
* [Fortrabbit](http://www.fortrabbit.com/)
* [PagodaBox](https://pagodabox.io/)
* [Heroku](https://www.heroku.com/)
* [Cloudways](https://www.cloudways.com/)
* [Liara](https://liara.ir/)

**Other Useful Resources**

**Laracasts**

* [Laracasts](https://laracasts.com/)

**Starter Kits**

* [Laravel 5 Boilerplate with Gentelella Admin Theme](https://github.com/Labs64/laravel-boilerplate)

**Youtube Channels**

* [Laracon](https://www.youtube.com/channel/UCRawXmZv30Vf_MivyPYb_GQ)
* [Laracon EU](https://www.youtube.com/channel/UCb9XEo_1SDNR8Ucpbktrg5A)
* [php\[architect\]](https://www.youtube.com/channel/UCUEzH08rDNBfljD9PGVZujg)
* [phpacademy](https://www.youtube.com/user/phpacademy)

**Paid Videos**

* [Udemy - Laravel for beginners](https://www.udemy.com/php-with-laravel-for-beginners-become-a-master-in-laravel/)

**Books**

* [**Laravel from Apprentice to Artisan** by Taylor Otwell](https://leanpub.com/laravel)
* [**Laravel Testing Decoded** by Jeffrey Way](https://leanpub.com/laravel-testing-decoded)
* [**Implementing Laravel** by Chris Fidao](https://leanpub.com/implementinglaravel)
* [**Laravel Application Development Cookbook** by Terryu Matula](https://www.packtpub.com/web-development/laravel-application-development-cookbook)
* [**Laravel: Code Bright** by Dayle Rees](https://leanpub.com/codebright)
* [**Laravel 5 Essentials** by Martin Bean](https://www.packtpub.com/web-development/laravel-5-essentials)
* [Laravel Books on leanpub](https://leanpub.com/book_search?search=laravel)
* [**Laravel: Up and Running** by Matt Stauffer](https://laravelupandrunning.com/)
* open for suggestions


# Internal SOPs

Management Standard Operating Procedures that keep us running smoothly

### Frequent Commits:

It's not good to push code only at the end of full task completion, rather you should keep committing/pushing code in between small changes of your task. For example, in case of a Users CRUD, once you complete its index page with backend controller just push it, then once you complete Create page with backend just push it and so on.

### Commit descriptions:

Make your descriptions meaningful. There’s nothing more frustrating than looking for a team members change from 2 weeks ago, and finding it hidden in a commit labelled “minor changes”. Describe what the code change does. Is it UI or Controller? Is it a Model or a Migration?

### Include Commands in the description to help team members:

If your commit requires other members of the team to run a new command after pulling your code, help them by adding this at the end of the commit description. Always use square brackets and capitals. Eg. \[MIGRATE] or \[COMPOSER INSTALL] or \[RESEED]

When your team mates pull your new code, they can quickly see what extra steps are required.

### Continuous and Real-Time tracking on invoices.larasoft.io:

Keep your time tracking diligently. Make sure you add the task you are working on in the correct Project. Use the Play/Stop buttons at the start and end of the time you have worked on the task. You can manually edit the time if you have accidentally left it running. It’s not good practice to work the full day then add the time manually at the end. It leaves too much scope for errors and inaccuracy. If you need to add lots of time manually, speak to Fahad.

### Track in the correct Project:

Projects are sometimes split into “\[Name] - Fixed Price” and “\[Name] - Per Hour”, so make sure you are clear if the task is billable to the client or it should be included as part of the original specification. In general, if a task was part of the original specification, or is a bug as part of the original specification, it should be included in a Fixed Price. If it is outside the original specification, or is a major change from that specification, then we will agree with the client that it is a “Change Request” and that they will be billed separately for it.

Hours in the Fixed Price = Not billed to the client.

Hours in Per Hour = Billed to the client at the end of each week.

### Mark tasks as completed

If you have completed a task, please mark it as competed. This will greatly reduce the steps at the end of the week to generate client’s invoices. It also keeps the project space clean and easy to read.

### Detail Detail Detail.

Take care and pay attention to the detail of your work. If a client has made some specification then you must follow it exactly. That includes any UI design that they have given you. The client will be frustrated if you submit work that does not look like the designs they have given you, or if you change something even slightly. If you think there is a better way to handle something, then submit your insight to the client for consideration. You will have lots of experience to provide insight into the best ways to handle something, but if the client is not involved in the decision making, it will look like you have not followed the specification.

### British English vs American English

Be aware that there are different customs in British English and American English. They differ very slightly. Be aware of where your client comes from, are they US based, or Europe based? Australia & Europe will generally follow British English customs.

American English has spellings like Co**lor**, Hu**mor**, Apolo**gize** and Custo**mize**.

British English has spellings like Col**our**, Hum**our**, Apolo**gise** and Custo**mise**.

American English follows date formats like mm/dd/yyyy

British English follows date formats like dd/mm/yyyy

This can be very confusing when presenting a date like 01/02/2020. Is this 2nd Jan or 1st Feb?? It depends which country your client lives in!

### API Keys and other Variables

ALWAYS ALWAYS ALWAYS – load API keys from the .env file. There is no exceptions, not even for development. Never hardcode an API key inside a .js file or a component file. One day, you will deploy that application to the client’s Live Server, the application will be large and complex, and you WILL NOT remember where all the API keys are located. You will one day forget an API key, and your demo keys will be mistakenly left on a Live Server… big problems will ensue and many hours of sleep will be lost….

This is why the .env file exists! One simple place to change all the keys from test/development/sandbox accounts, so that your client can use the APIs and third party services without demo restrictions.


