├── .gitattributes
├── .vitepress
├── .gitignore
├── theme
│ ├── tailwind.css
│ ├── index.ts
│ └── style.css
├── README.md
└── config.mts
├── development
├── README.md
└── library
│ ├── back-end
│ ├── conventions--sql.md
│ ├── conventions--php.md
│ └── conventions--laravel.md
│ └── front-end
│ ├── conventions--js.md
│ ├── conventions--css.md
│ ├── conventions--jsdoc.md
│ └── conventions--vue.md
├── .gitignore
├── .prettierrc
├── public
├── README.md
├── favicons
│ ├── favicon.ico
│ └── apple-touch-icon.png
└── images
│ └── hydrogenlogo.svg
├── postcss.config.js
├── .github
├── renovate.json
├── workflows
│ ├── auto_update_npm_updates.yml
│ ├── spelling.yml
│ └── format.yml
└── config.yml
├── .typos.toml
├── guides
├── OKR
│ ├── 00-benefits-of-okrs.md
│ ├── 00-history-of-okrs.md
│ ├── README.md
│ ├── 02-cascading-okrs.md
│ ├── 05-assess-your-okrs.md
│ ├── 01-okr-cadence.md
│ ├── 00-why-okrs.md
│ ├── 04-stay-aligned-as-a-team.md
│ └── 03-create-your-okrs.md
├── roles
│ ├── support-engineer.md
│ └── senior-developer.md
├── onboarding
│ ├── onboarding--domain-knowledge.md
│ ├── README.md
│ └── onboarding--buddyGuide.md
├── people-operations
│ ├── video-calls.md
│ └── team-trips.md
└── collaboration-tools.md
├── outdated
├── design-products
│ ├── README.md
│ ├── design-principles.md
│ └── delivery-process.md
├── achieve-purpose
│ ├── README.md
│ ├── vision.md
│ └── mission.md
├── development
│ └── README.md
└── scrum
│ ├── backlog.md
│ └── README.md
├── library
├── backend
│ ├── README.md
│ ├── conventions--sql.md
│ ├── literature.md
│ ├── SOLID.md
│ └── conventions--php.md
└── frontend
│ ├── use-the-platform.md
│ ├── README.md
│ ├── conventions--css.md
│ ├── conventions--js.md
│ ├── literature.md
│ ├── conventions--jsdoc.md
│ └── conventions--vuejs.md
├── .editorconfig
├── CONTRIBUTING.md
├── tailwind.config.js
├── LICENSE
├── package.json
├── README.md
├── index.md
└── images
├── agile-sprints.svg
└── continuous-delivery.svg
/.gitattributes:
--------------------------------------------------------------------------------
1 | *.md text eol=lf
2 |
--------------------------------------------------------------------------------
/.vitepress/.gitignore:
--------------------------------------------------------------------------------
1 | /cache
2 | /dist
3 |
--------------------------------------------------------------------------------
/development/README.md:
--------------------------------------------------------------------------------
1 | This directory is deprecated.
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # ignore temporary files
2 | .DS_Store
3 | /node_modules
4 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "bracketSpacing": false,
3 | "singleQuote": true
4 | }
5 |
--------------------------------------------------------------------------------
/public/README.md:
--------------------------------------------------------------------------------
1 | See https://vitepress.dev/guide/asset-handling#the-public-directory
2 |
--------------------------------------------------------------------------------
/public/favicons/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/InteractionDesignFoundation/handbook/HEAD/public/favicons/favicon.ico
--------------------------------------------------------------------------------
/.vitepress/theme/tailwind.css:
--------------------------------------------------------------------------------
1 | @import './style.css';
2 |
3 | @tailwind base;
4 | @tailwind components;
5 | @tailwind utilities;
6 |
7 |
--------------------------------------------------------------------------------
/public/favicons/apple-touch-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/InteractionDesignFoundation/handbook/HEAD/public/favicons/apple-touch-icon.png
--------------------------------------------------------------------------------
/postcss.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: {
3 | 'postcss-import': {},
4 | tailwindcss: {},
5 | autoprefixer: {},
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/.github/renovate.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json",
3 | "extends": [
4 | "local>InteractionDesignFoundation/.github:renovate-config-security-updates-only"
5 | ]
6 | }
7 |
--------------------------------------------------------------------------------
/.typos.toml:
--------------------------------------------------------------------------------
1 | [files]
2 | extend-exclude = [
3 | ".git/",
4 | ]
5 | ignore-hidden = false
6 |
7 | [default.extend-words]
8 | invokable = "invokable"
9 |
10 | [default.extend-identifiers]
11 | # Typos
12 | "Github" = "GitHub"
13 |
--------------------------------------------------------------------------------
/development/library/back-end/conventions--sql.md:
--------------------------------------------------------------------------------
1 | The document is moved.
2 | New URL is [SQL conventions](../../../library/backend/conventions--sql).
3 |
4 | Please report/fix a broken link on the external source — we’ll remove these stub/redirect pages soon.
5 |
--------------------------------------------------------------------------------
/development/library/front-end/conventions--js.md:
--------------------------------------------------------------------------------
1 | The document is moved.
2 | New URL is [JS conventions](../../../library/frontend/conventions--js).
3 |
4 | Please report/fix a broken link on the external source — we’ll remove these stub/redirect pages soon.
5 |
--------------------------------------------------------------------------------
/development/library/back-end/conventions--php.md:
--------------------------------------------------------------------------------
1 | The document is moved.
2 | New URL is [PHP conventions](../../../library/backend/conventions--php.md).
3 |
4 | Please report/fix a broken link on the external source — we’ll remove these stub/redirect pages soon.
5 |
--------------------------------------------------------------------------------
/development/library/front-end/conventions--css.md:
--------------------------------------------------------------------------------
1 | The document is moved.
2 | New URL is [CSS conventions](../../../library/frontend/conventions--css).
3 |
4 | Please report/fix a broken link on the external source — we’ll remove these stub/redirect pages soon.
5 |
--------------------------------------------------------------------------------
/development/library/front-end/conventions--jsdoc.md:
--------------------------------------------------------------------------------
1 | The document is moved.
2 | New URL is [JSDoc conventions](../../../library/frontend/conventions--js).
3 |
4 | Please report/fix a broken link on the external source — we’ll remove these stub/redirect pages soon.
5 |
--------------------------------------------------------------------------------
/development/library/front-end/conventions--vue.md:
--------------------------------------------------------------------------------
1 | The document is moved.
2 | New URL is [Vue conventions](../../../library/frontend/conventions--vuejs).
3 |
4 | Please report/fix a broken link on the external source — we’ll remove these stub/redirect pages soon.
5 |
--------------------------------------------------------------------------------
/development/library/back-end/conventions--laravel.md:
--------------------------------------------------------------------------------
1 | The document is moved.
2 | New URL is [Laravel conventions](../../../library/backend/conventions--laravel).
3 |
4 | Please report/fix a broken link on the external source — we’ll remove these stub/redirect pages soon.
5 |
--------------------------------------------------------------------------------
/guides/OKR/00-benefits-of-okrs.md:
--------------------------------------------------------------------------------
1 | # Benefits of OKRs
2 |
3 | 
4 |
5 | 
6 |
7 | 
8 |
9 | 
10 |
--------------------------------------------------------------------------------
/guides/OKR/00-history-of-okrs.md:
--------------------------------------------------------------------------------
1 | # OKR History
2 |
3 | ## Historical Development of OKRs
4 |
5 | 
6 |
7 | ## The OKR Approach and its Relation to Other Methods
8 |
9 | 
10 |
--------------------------------------------------------------------------------
/outdated/design-products/README.md:
--------------------------------------------------------------------------------
1 | # Design Products
2 |
3 | 
4 |
5 | The IxDF Design Process is heavily informed by our [design principles](/outdated/design-products/design-principles.md) and enables us to [deliver](/outdated/design-products/delivery-process.md) value to our Members..
6 |
--------------------------------------------------------------------------------
/library/backend/README.md:
--------------------------------------------------------------------------------
1 | # Library: Backend
2 |
3 | ## Table of Contents
4 |
5 | - [IxDF conventions for PHP](conventions--php.md)
6 | - [IxDF conventions for Laravel](conventions--laravel.md)
7 | - [Clean Code Principles for PHP](clean-code-php.md)
8 | - [S.O.L.I.D. Principles for PHP](SOLID.md)
9 | - [Literature](literature.md)
10 |
11 | 🦄
12 |
--------------------------------------------------------------------------------
/outdated/achieve-purpose/README.md:
--------------------------------------------------------------------------------
1 | # Achieve Our Purpose
2 |
3 | 
4 |
5 | The IxDF has a big purpose that requires us to work hard, and to work together,
6 | so each person in the IxDF must understand the **[Vision for the future of the IxDF](/outdated/achieve-purpose/vision.md)**,
7 | and carry out the daily **[Mission](/outdated/achieve-purpose/mission.md)** to bring about that vision.
8 |
--------------------------------------------------------------------------------
/library/frontend/use-the-platform.md:
--------------------------------------------------------------------------------
1 | # #UseThePlatform
2 |
3 | A list of useful resources that follows #UseThePlatform principles:
4 |
5 | - [The Vanilla JavaScript Repository](https://vanillalist.top/)
6 | - [Web Components created by GitHub](https://github.com/search?q=topic%3Aweb-components+org%3Agithub&type=repositories)
7 | - [What PWA Can Do Today](https://whatpwacando.today/)
8 | - [Plain Vanilla](https://plainvanillaweb.com/)
9 |
--------------------------------------------------------------------------------
/.github/workflows/auto_update_npm_updates.yml:
--------------------------------------------------------------------------------
1 | name: NPM PRs auto-merge
2 |
3 | on:
4 | schedule:
5 | - cron: "0 12 * * *"
6 |
7 | jobs:
8 | merge:
9 | name: "Auto-merge patch updates"
10 | runs-on: ubuntu-latest
11 | steps:
12 | - uses: AnandChowdhary/dependabot-pr-action@master
13 | with:
14 | token: ${{ secrets.GITHUB_TOKEN }}
15 | merge-minor: false
16 | merge-patch: true
17 |
--------------------------------------------------------------------------------
/.vitepress/theme/index.ts:
--------------------------------------------------------------------------------
1 | // https://vitepress.dev/guide/custom-theme
2 | import { h } from 'vue'
3 | import Theme from 'vitepress/theme'
4 | import './tailwind.css';
5 |
6 | export default {
7 | extends: Theme,
8 | Layout: () => {
9 | return h(Theme.Layout, null, {
10 | // https://vitepress.dev/guide/extending-default-theme#layout-slots
11 | })
12 | },
13 | enhanceApp({ app, router, siteData }) {
14 | // ...
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/library/frontend/README.md:
--------------------------------------------------------------------------------
1 | # Library: Frontend
2 |
3 | ## Table of Contents
4 |
5 | - [IxDF conventions for JavaScript](conventions--js.md)
6 | - [IxDF conventions for JSDoc](conventions--jsdoc.md)
7 | - [IxDF conventions for Vue](conventions--vuejs.md)
8 | - [IxDF conventions for CSS](conventions--css.md)
9 | - [Clean Code Principles for JavaScript](clean-code-js.md)
10 | - [Literature](conventions--css.md)
11 | - [#UseThePlatform](use-the-platform.md)
12 |
13 | 🦄
14 |
--------------------------------------------------------------------------------
/.vitepress/README.md:
--------------------------------------------------------------------------------
1 | # VitePress
2 |
3 | We use VitePress in a bit different way how it was intended to be used. We use it as a static site generator for our documentation.
4 | That's why we have additional steps during a building process.
5 |
6 | ## Build
7 |
8 | Build and preview:
9 |
10 | ```shell
11 | yarn docs:build
12 | yarn docs:preview
13 | ```
14 |
15 | Live view (with live reload):
16 |
17 | ```shell
18 | yarn docs:dev
19 | ```
20 |
21 | ## Materials
22 |
23 | - https://vitepress.dev/guide/getting-started
24 |
--------------------------------------------------------------------------------
/.github/workflows/spelling.yml:
--------------------------------------------------------------------------------
1 | name: "Spelling"
2 |
3 | on:
4 | workflow_dispatch:
5 | pull_request:
6 | push:
7 | branches:
8 | - "main"
9 |
10 | permissions:
11 | contents: "read"
12 |
13 | concurrency:
14 | group: "${{ github.workflow }}-${{ github.ref }}"
15 | cancel-in-progress: true
16 |
17 | jobs:
18 | typos_check:
19 | name: "Typos check"
20 | runs-on: ubuntu-latest
21 | timeout-minutes: 1
22 | steps:
23 | - uses: actions/checkout@v4
24 |
25 | - uses: crate-ci/typos@master
26 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | charset = utf-8
5 | end_of_line = lf
6 | insert_final_newline = true
7 | indent_style = space
8 | indent_size = 4
9 | trim_trailing_whitespace = true
10 | max_line_length = 120
11 | tab_width = 4
12 | block_comment_start = /*
13 | block_comment = *
14 | block_comment_end = */
15 |
16 | [*.md]
17 | #indent_size = 2
18 | trim_trailing_whitespace = false
19 | max_line_length = 500
20 |
21 | [*.{yml,yaml}]
22 | indent_size = 2
23 |
24 | [yarn.lock]
25 | indent_size = 2
26 | max_line_length = unset
27 |
28 | [*.svg]
29 | max_line_length = unset
30 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 |
3 | Welcome to the Employee Handbook repository!
4 | We appreciate your interest in contributing to this project.
5 | This document outlines the guidelines for contributing to the Employee Handbook repository.
6 | Please take a moment to read through this guide to ensure a smooth and collaborative contribution process.
7 |
8 | ## Rules
9 |
10 | 1. Use American English as the standard written language.
11 | 1. Please keep clear file structure.
12 | 1. Do not create links like "here" or "click here". All links should have relevant anchor text that describes what they link to.
13 |
--------------------------------------------------------------------------------
/outdated/achieve-purpose/vision.md:
--------------------------------------------------------------------------------
1 | # Vision for the future of the IxDF
2 |
3 | So, what’s the vision of the IxDF? What’s the future path for our mission, so to speak?
4 | What are we going to achieve together and strive towards, as a team – today and in the future?
5 |
6 | - To become the very best, the most well-known and the most prestigious design school in the world and the one-stop destination for designers to learn new skills
7 | - To have the very best learning platform, learning process and learning content for designers on the planet.
8 | - To have a true high-performance culture of high performance and excellence.
9 |
--------------------------------------------------------------------------------
/.github/workflows/format.yml:
--------------------------------------------------------------------------------
1 | name: Format
2 |
3 | on:
4 | push:
5 | paths:
6 | - "**.md"
7 | - "**.json"
8 |
9 | jobs:
10 | prettier:
11 | runs-on: ubuntu-latest
12 | steps:
13 | - uses: actions/checkout@v4
14 |
15 | - uses: actions/setup-node@v4
16 | with:
17 | node-version: 20
18 | cache: 'yarn'
19 |
20 | - name: Install
21 | run: yarn install
22 | env:
23 | CI: true
24 |
25 | - name: Run formatting tool
26 | run: yarn style:fix
27 |
28 | - uses: stefanzweifel/git-auto-commit-action@v4
29 | with:
30 | commit_message: "✨ Apply formatting changes"
31 | env:
32 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
33 |
--------------------------------------------------------------------------------
/outdated/achieve-purpose/mission.md:
--------------------------------------------------------------------------------
1 | # Our Mission
2 |
3 | Our mission is to genuinely improve the world by creating design education of the highest quality and the lowest possible cost.
4 | We help as many designers, companies and students as possible improve their skills and future prospects—regardless of their location or background.
5 | This is the reason we exist.
6 |
7 | We LOVE that we make a big difference to millions of people around the world.
8 |
9 | Not only do we help millions build a better future for themselves, but we also teach them to apply their new design skills to improve the quality of life for humankind.
10 | We live in a world filled with inefficient and inhumane design—there lies a huge opportunity to make a positive impact through great design!
11 |
--------------------------------------------------------------------------------
/guides/OKR/README.md:
--------------------------------------------------------------------------------
1 | # Coordinate Efforts
2 |
3 | 
4 |
5 | When you have a grand global [vision](/outdated/achieve-purpose/vision.md)
6 | and a [mission](/outdated/achieve-purpose/mission.md) to achieve that vision with the highest possible quality
7 | at the lowest possible cost for millions of people, you are only going to succeed with hard work and great team coordination.
8 |
9 | To achieve this at the IxDF, we hire unicorn team members, maintain a high-performance culture,
10 | and use frameworks like scrum, agile and OKRs (Objectives and Key Results).
11 |
12 | If you are not already familiar, you can learn more [about OKRs](./00-why-okrs),
13 | or about the [benefits of OKRs](./00-benefits-of-okrs).
14 |
15 | If you are already familiar and want to start using OKRs as an IxDF staff,
16 | please start with [our OKR cadence](./01-okr-cadence).
17 |
--------------------------------------------------------------------------------
/tailwind.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('tailwindcss').Config} */
2 | export default {
3 | content: [
4 | './index.md',
5 | './docs/.vitepress/**/*.{js,ts,vue}',
6 | './docs/**/*.md',
7 | './vitepress/**/*.{js,ts,vue}',
8 | './development/**/*.md',
9 | './development/**/**/*.md',
10 | './guides/**/*.md',
11 | './guides/**/**/*.md',
12 | './library/**/*.md',
13 | './library/**/**/*.md',
14 | './outdated/**/*.md',
15 | './outdated/**/**/*.md',
16 | './docs/**/*.md',
17 | ],
18 | theme: {
19 | extend: {},
20 | screens: {
21 | 'sm': '640px',
22 | // => @media (min-width: 640px) { ... }
23 |
24 | 'md': '768px',
25 | // => @media (min-width: 768px) { ... }
26 |
27 | 'lg': '1056px',
28 | // => @media (min-width: 1056px) { ... }
29 |
30 | 'xl': '1280px',
31 | // => @media (min-width: 1280px) { ... }
32 |
33 | '2xl': '1536px',
34 | // => @media (min-width: 1536px) { ... }
35 | }
36 | },
37 | plugins: [],
38 | }
39 |
--------------------------------------------------------------------------------
/guides/OKR/02-cascading-okrs.md:
--------------------------------------------------------------------------------
1 | # Cascading OKRs
2 |
3 | What are Cascading OKR's?
4 | Like similar systems (e.g., [Cascading Stylesheets](https://developer.mozilla.org/en-US/docs/Web/CSS)),
5 | attributes and changes at one level of OKR are reflected in other levels of OKR.
6 | For example, when a new IxDF-wide OKR is created or changed and communicated by the IxDF Executive Level,
7 | each Team and Individual OKR as adjusted each quarter to support it.
8 |
9 | 
10 |
11 | This helps to align all of our individual, team, and organizational OKRs are aligned and helping to achieve the IxDF's mission and vision.
12 |
13 | 
14 |
15 | Here is what the process looks like over the course of a normal quarter.
16 |
17 | 
18 |
19 | Now that you have seen how our OKRs work at the organizational level, it’s time to start [creating your OKR's](./03-create-your-okrs).
20 |
--------------------------------------------------------------------------------
/guides/OKR/05-assess-your-okrs.md:
--------------------------------------------------------------------------------
1 | # Assess Your OKRs
2 |
3 | By the end of the quarter, you and your Team give each Key Result a final score, and reflect on your OKRs as a whole. Using a retrospective approach, pose some (or all) of these questions to your Team:
4 |
5 | - Were our Objectives ambitious enough?
6 | - Were our Key Results measurable? Did we know what our baseline was at the start of the quarter?
7 | - Did we “set ’em and forget ’em”? If so, why?
8 | - Were our OKRs aligned with the IxDF’s broader strategies?
9 | - Did they keep us focused on delivering value to customers?
10 | - Did we feel connected to our OKRs?
11 | - What have we learned from this quarter? How do we lift the bar moving into the coming quarter?
12 |
13 | ## Hold the Quarterly Meeting
14 |
15 | At the end of each quarter, you evaluate your own and your Team’s OKRs in order to measure your accomplishment
16 |
17 | 
18 |
19 | ## The Meeting
20 |
21 | 
22 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 The Interaction Design Foundation
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/outdated/design-products/design-principles.md:
--------------------------------------------------------------------------------
1 | # Design Principles
2 |
3 | Design is the art of making smart, effective decisions that create a desirable outcome. We use a set of 11 Design Principles to help guide our decisions. We began with the Ten Principles of Good Design by Industrial Designer Dieter Rams which we continue to adapt for our own purposes.
4 |
5 | 1. Good design is **innovative**—It does not automatically follow convention.
6 | 1. Good design makes a product **useful**—It does work for people.
7 | 1. Good design is **aesthetically beautiful**—It makes your heart skip a beat.
8 | 1. Good design makes a product **understandable**—Anyone can use it instantly.
9 | 1. Good design is **unobtrusive**—It lets the content, learner, instructors shine.
10 | 1. Good design is **honest**—”I know exactly who designed this!”
11 | 1. Good design is **long-lasting**—Hot new trends don’t worry us.
12 | 1. Good design is **thorough** down to the last detail—We care about it all.
13 | 1. Good design is **good for everyone**—All people and the living things around them.
14 | 1. Good design is **as little design as possible**—If it doesn’t add value, it’s not going in the design.
15 | 1. Good design **teaches**—Experiencing it should help me then apply it
16 |
--------------------------------------------------------------------------------
/guides/OKR/01-okr-cadence.md:
--------------------------------------------------------------------------------
1 | # OKR Cadence
2 |
3 | A good process is repeatable, has a good cadence. The IxDF OKR process is broken into 3-month cycles.
4 |
5 | 
6 |
7 | At the start of each cycle, Quarterly Goals are set for the whole IxDF based on the [Vision](/outdated/achieve-purpose/vision.md) and [Mission](/outdated/achieve-purpose/mission.md). Teams and Individuals plan and align their OKRs and begin a series of six 2-week Sprints.
8 |
9 | 
10 |
11 | At the end of the cycle, each team has an OKR Retrospective to improve the OKR Process and an OKR Review to analyze the progress on each OKR.
12 |
13 | By aligning quarterly objectives with annual objectives that are set at the start of the year, it is possible to see how daily tasks contribute to key results, quarterly objectives, annual objectives and the IxDF mission and vision.
14 |
15 | 
16 |
17 | This then allows us to align our strategic goals and planning with our daily execution of tasks.
18 |
19 | 
20 |
21 | Below is a more detailed view of our yearly IxDF-wide OKR process.
22 |
23 | 
24 |
25 | And here is a view of what this looks like at the team level.
26 |
27 | 
28 |
--------------------------------------------------------------------------------
/outdated/development/README.md:
--------------------------------------------------------------------------------
1 | # Develop Software
2 |
3 | 
4 |
5 | At IxDF, we're building an open and transparent company, full of people who love their work and enjoy the challenges they face every day.
6 | To achieve this, we want everyone to understand what is expected of them, the things we value and the things we believe should be avoided.
7 |
8 | ## Table of Contents
9 |
10 | - Guides
11 | - [Onboarding](/guides/onboarding/README.md)
12 | - People Operations
13 | - [Team Trips](/guides/people-operations/team-trips.md)
14 | - [Video Calls](/guides/people-operations/video-calls.md)
15 | - [Scrum](/outdated/scrum/README.md)
16 | - [Our expectations from you and your work](/guides/roles/senior-developer.md)
17 | - [Collaboration tools](/guides/collaboration-tools.md)
18 | - Library
19 | - [Back end](/library/backend/README.md)
20 | - [Front end](/library/frontend/README.md)
21 |
22 | ## Links
23 |
24 | - [Handbook contribution guide](/CONTRIBUTING.md): how to make this document even better 🦄
25 | - 🔒 Shared folders at [Dropbox.com](https://www.dropbox.com/share/) (ask **@mads** to give you access)
26 | - [🔒 developer docs](https://github.com/InteractionDesignFoundation/IxDF-web/blob/main/docs/README.md) - development-related documents
27 |
28 | ## The IxDF Zen Code
29 |
30 | 
31 |
32 | 🦄
33 |
--------------------------------------------------------------------------------
/guides/roles/support-engineer.md:
--------------------------------------------------------------------------------
1 | # Support engineer
2 |
3 | :::tip More you can find in internal documentation
4 | This is only a basic version of the documentation.
5 | [Full documentation](https://docs.information-architecture.org/workflows/roles/support-engineer.html) contains some content that we don’t want to open-source for security reasons.
6 | :::
7 |
8 | [[toc]]
9 |
10 | By agreement, at least one engineer is assigned the support engineer role and usually stay on it for 1-2 weeks only.
11 | This role is usually assigned to developers who have just completed
12 | a large feature or some other large task who need some time to keep an eye on things and recover energy.
13 |
14 | ## Why do we have this role?
15 |
16 | The main goal is to allow other developers to focus on bigger tasks while support engineers work ongoing bug reports
17 | and help other teams with their tasks.
18 |
19 | ## Your responsibilities
20 |
21 | This role can be a challenging one as it involves a lot of critical thinking and initiative.
22 | In a nutshell, your goal is to protect the dev team from distractions while still making sure
23 | that the needs of the business are taking care of.
24 |
25 | You have done a great job as a support engineer when:
26 |
27 | 1. The dev team can confidently mute error channels and notifications knowing that you are constantly monitoring for errors and performance issues
28 | 2. The dev team can focus almost entirely on their sprint goals, knowing that you will only involve them if its really important that you do so
29 | 3. Other teams feel like their requests are being heard and taken care of in a timely manner
30 |
--------------------------------------------------------------------------------
/guides/onboarding/onboarding--domain-knowledge.md:
--------------------------------------------------------------------------------
1 | # How to get domain knowledge
2 |
3 | We’ve developed a few onboarding activities to give you a much deeper understanding
4 | of our domain. Understanding our domain, i.e. the platform and its features from
5 | our **users’ perspective** (i.e. domain knowledge) is paramount to both understanding
6 | our codebase and writing awesome code. Great code has a **“small conceptual distance”**
7 | to the domain. In other words, it brings cognitive ease when variables, methods, database tables,
8 | models, services, operations, and likewise come directly from domain-specific vocabulary.
9 |
10 | Don’t expect to grasp/understand/remember everything you read during your onboarding.
11 | Look at it as a map which you can refer to down the road.
12 |
13 | ## Read docs from `/docs/domain`
14 |
15 | In our main repository we have [🔒 `/docs/domain/`](https://github.com/InteractionDesignFoundation/IxDF-web/tree/main/docs/domain) directory with README.md file for every system/module we have on our application.
16 | Such `README.md` files provide a brief overview of the system and usually contains links to other docs with deeper technical details.
17 | During onboarding, you need to read `README.md` files for every system.
18 |
19 | ## Test email notifications
20 |
21 | Go to the [notification control panel](https://develop.information-architecture.org/admin/notifications)
22 | on our staging/test sites (You can find the basic-auth credentials in lastpass).
23 | On that page, you will see information on how to test an email notification.
24 |
25 | Please be **absolutely sure** you’re not on the production server but on a **staging/test site**.
26 |
27 | Doing this activity can feel a bit grinding, but rest assured that it will pay off
28 | in the long run. It will make your work in the codebase considerably easier.
29 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ixdf-handbook",
3 | "description": "IxDF Company handbook for developers",
4 | "main": "README.md",
5 | "private": true,
6 | "type": "module",
7 | "scripts": {
8 | "test": "npm run style:lint",
9 | "style:lint": "prettier \"**/*.md\"",
10 | "style:fix": "prettier \"**/*.md\" --write",
11 | "docs:build": "vitepress build",
12 | "docs:dev": "vitepress dev",
13 | "docs:preview": "vitepress preview",
14 | "docs:fix": "prettier \"**/*.md\" --write"
15 | },
16 | "engines": {
17 | "node": ">=20.0"
18 | },
19 | "repository": {
20 | "type": "git",
21 | "url": "git+https://github.com/InteractionDesignFoundation/handbook.git"
22 | },
23 | "keywords": [
24 | "handbook",
25 | "company culture",
26 | "engineering culture"
27 | ],
28 | "bugs": {
29 | "url": "https://github.com/InteractionDesignFoundation/handbook/issues"
30 | },
31 | "homepage": "https://github.com/InteractionDesignFoundation/handbook#readme",
32 | "dependencies": {
33 | "autoprefixer": "^10.4.19",
34 | "husky": "^8.0.3",
35 | "mermaid": "^11.10.0",
36 | "postcss": "^8.4.39",
37 | "postcss-import": "^16.1.0",
38 | "prettier": "^3.1",
39 | "pretty-quick": "^3.1.3",
40 | "tailwindcss": "^3.4.4"
41 | },
42 | "postcss": {
43 | "plugins": {
44 | "postcss-import": {},
45 | "tailwindcss": {},
46 | "autoprefixer": {}
47 | }
48 | },
49 | "devDependencies": {
50 | "vitepress": "^1.0",
51 | "vitepress-plugin-mermaid": "^2.0.16",
52 | "vitepress-sidebar": "^1.18.5"
53 | },
54 | "husky": {
55 | "hooks": {
56 | "pre-commit": "pretty-quick --staged"
57 | }
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | # IxDF Dev Handbook
10 |
11 | At IxDF, we're building an open and transparent company, full of people who love their work and enjoy the challenges they face every day.
12 | To achieve this, we want everyone to understand what is expected of them, the things we value and the things we believe should be avoided.
13 |
14 | ## Table of Contents
15 |
16 | - Guides
17 | - [Onboarding](/guides/onboarding/README.md)
18 | - People Operations
19 | - [Team Trips](/guides/people-operations/team-trips.md)
20 | - [Video Calls](/guides/people-operations/video-calls.md)
21 | - [Collaboration tools](/guides/collaboration-tools.md)
22 | - Roles
23 | - [Senior Developer](/guides/roles/senior-developer.md)
24 | - [Support engineer](/guides/roles/support-engineer.md)
25 | - Library
26 | - [Back end](/library/backend/README.md)
27 | - [PHP conventions](/library/backend/conventions--php.md)
28 | - [Laravel conventions](/library/backend/conventions--laravel.md)
29 | - [Front end](/library/frontend/README.md)
30 | - [JS conventions](/library/frontend/conventions--js.md)
31 | - [JSDoc conventions](/library/frontend/conventions--js.md)
32 | - [Vue conventions](/library/frontend/conventions--vuejs.md)
33 | - [CSS conventions](/library/frontend/conventions--css.md)
34 |
35 | 🦄
36 |
--------------------------------------------------------------------------------
/outdated/scrum/backlog.md:
--------------------------------------------------------------------------------
1 | # How to plan your backlog
2 |
3 | - When choosing issues for an upcoming sprint, you can use "6 ideal work hours per day" as a reference point. An ideal work hour is an hour spent on an issue with a complete focus — no interruptions. It makes 60 ideal work hours per sprint (30 hours per week). During these "ideal work hours" you're in complete focus/concentration, i.e. "in the zone". The rest of your time, you’ll spend on coordination, "work about work", small-ish issues, meetings, and lots of other stuff.
4 | - Search for issues with the label `urgency:X` (where X is a number from 8 to 10) assigned to you (for developers, this would usually be critical bugs). You should include them into your next sprint - or do them right now if you have an empty backlog.
5 | - After that, choose all unfinished "important"(1) issues from the previous sprint that you've not managed to finish. They should be carried over to the next sprint.
6 | - Next pick "important"(1) issues selected by ProductOwner as goals for next sprint.
7 | - Finally, choose any other issues that will fill up your backlog so you have enough to do for the following sprint. Remember to pick these issues on what will get us most effectively/efficiently towards our short/mid/long-term goals and our vision.
8 | - Don’t forget to include all critical issues and other urgent priority issues (if any) to the upcoming sprint.
9 |
10 | When you do the Sprint Planning, ahead of the Sprint Planning Meeting, then make sure to add `next sprint` label for all issues you are going to add to your backlog: it will help us to:
11 |
12 | - filter out all your planned issues for easier review
13 | - automatically move issues to your backlog (by using a script)
14 |
15 | ---
16 |
17 | (1) "important" issues are those that add value to our platform; either for our end users or our staff, ProductOwner defines them. We usually mark them by `importance: high` label.
18 |
--------------------------------------------------------------------------------
/guides/people-operations/video-calls.md:
--------------------------------------------------------------------------------
1 | # Video Calls
2 |
3 | We're an all-remote company that allows people to work from almost anywhere in the world.
4 | We hire great people regardless of where they live, but with colleagues from 10+ timezones (and counting)
5 | it’s important for us to practice clear communication that helps us stay connected and get things done.
6 | For this, we use asynchronous communication as a start and are as open as we can be by communicating
7 | through issues tracker (GitHub), Slack channels, and placing an emphasis on ensuring that conclusions
8 | of offline conversations are written down.
9 | When we go **back and forth three times** we jump on a synchronous video call.
10 | These communication guidelines are meant to facilitate smooth communication in an ever-growing, all-remote company.
11 |
12 | 1. We start on time and do not wait for people. People are expected to join no later than the scheduled minute of the meeting (before :01 if it is scheduled for :00). The question 'is everyone here' is not needed.
13 | 1. Always turn on video — unless the bandwidth suffers, at which point one or more people switch to audio-only.
14 | 1. Be mindful of background noise in your end. If you are in a noisy place, that noise will get transmitted to everyone
15 | and will interrupt the team's concentration. In this case, you merely mute and unmute your microphone
16 | whenever you are speaking/not speaking.
17 | 1. Make eye contact and be mentally 110% there so the developer who's talking can feel your presence
18 | and not feel like talking to a computer screen :-)
19 | 1. Pay attention to other team members; they may ask for help, OR you may notice that they need help without directly asking.
20 | Especially the daily calls are a chance for all of us to be on the same page AND help others to save time & sanity so that we operate as efficiently as possible.
21 | 1. Make sure you've read and re-read the guidelines on [Scrum overview](/outdated/scrum/README.md) so that you, for example, don’t give lengthy updates on insignificant stuff ("..and then I corrected a typo on page XYZ..." :-) )
22 |
23 | 🦄
24 |
--------------------------------------------------------------------------------
/guides/OKR/00-why-okrs.md:
--------------------------------------------------------------------------------
1 | # About OKRs
2 |
3 | ## WHAT are Objectives And Key Results (OKRs)?
4 |
5 | The OKR method is a popular strategy for setting and achieving goals within organizations. Like most organizations, we use [Cascading OKRs](./02-cascading-okrs), that allows us to align our vision, mission, values and strategy with day-to-day objectives, work and key results.
6 |
7 | 
8 |
9 | And because the OKR method is collaborative, it allows us to realize our vision and mission in the best possible way, by connecting our organizational, team, and personal goals to measurable results while having all Team Members and Team Leads work together in one, unified direction.
10 |
11 | ## Anatomy of an OKR
12 |
13 | Every OKR has three parts—an Objective, a Key Result and a Task.
14 |
15 | 
16 |
17 | ## OKR Examples
18 |
19 | Below are three example OKRs.
20 |
21 | 
22 |
23 | Note that in these examples the KPI's and tasks are combined. For example, in Example 02, "Develop five free articles" is a task, and "improve signups from X% to Y%" is a KPI that measures signups which indicates progress toward the Objective.
24 |
25 | ## WHY Do We Use OKRs?
26 |
27 | - OKRs bridge the gap between our [Vision](/outdated/achieve-purpose/vision.md), [Mission](../../outdated/achieve-purpose/mission.md), Strategy and the concrete Objectives and Key Results in our daily work.
28 | - OKRs help us create a weekly, quarterly, and yearly overview over how our daily tasks are connected to our vision, and therefore help us decide individually, and in our Teams, which steps are the best to take.
29 | - They help us track our individual and Team progress, create alignment in our Teams and across Teams so everyone moves towards achieving the same overall goals.
30 | - OKRs improve our focus and increase transparency within and across teams.
31 |
32 | 
33 |
34 | If you are still wondering, here are some more [benefits of OKRs](./00-benefits-of-okrs).
35 | Otherwise, if you are ready to start using OKRs at the IxDF, let's start with [our OKR cadence](./01-okr-cadence).
36 |
--------------------------------------------------------------------------------
/.github/config.yml:
--------------------------------------------------------------------------------
1 | # Configuration for welcome - https://github.com/behaviorbot/welcome
2 |
3 | # Configuration for new-issue-welcome - https://github.com/behaviorbot/new-issue-welcome
4 |
5 | # Comment to be posted to on first time issues
6 | newIssueWelcomeComment: >
7 | Wow, it’s your first issue here! We are glad that you want to improve this repository 🚀
8 |
9 | # Configuration for new-pr-welcome - https://github.com/behaviorbot/new-pr-welcome
10 |
11 | # Comment to be posted to on PRs from first time contributors in your repository
12 | newPRWelcomeComment: >
13 | Thanks for opening this pull request 🦄! Do you want to improve your PR? - Please check out our [contributing guidelines](https://github.com/InteractionDesignFoundation/handbook/blob/main/resources/contributing.md).
14 |
15 | # Configuration for first-pr-merge - https://github.com/behaviorbot/first-pr-merge
16 |
17 | # Comment to be posted to on pull requests merged by a first time user
18 | firstPRMergeComment: >
19 | Congrats on merging your first pull request! 🎉🎉🎉
20 |
21 | 
22 |
23 | # It is recommended to include as many gifs and emojis as possible!
24 |
25 | # Configuration for request-info - https://github.com/behaviorbot/request-info
26 |
27 | # *Required* Comment to reply with
28 | requestInfoReplyComment: >
29 | We would appreciate it if you could provide us with more info about this issue/PR!
30 |
31 | # *OPTIONAL* default titles to check against for lack of descriptiveness
32 | # MUST BE ALL LOWERCASE
33 | #requestInfoDefaultTitles:
34 | # - update readme.md
35 | # - updates
36 |
37 | # *OPTIONAL* Label to be added to Issues and Pull Requests with insufficient information given
38 | # requestInfoLabelToAdd: needs-more-info
39 |
40 | # *OPTIONAL* Only warn about insufficient information on these events type
41 | # Keys must be lowercase. Valid values are 'issue' and 'pullRequest'
42 | requestInfoOn:
43 | pullRequest: true
44 | issue: true
45 |
46 | # Configuration for sentiment-bot - https://github.com/behaviorbot/sentiment-bot
47 |
48 | # *Required* toxicity threshold between 0 and .99 with the higher numbers being the most toxic
49 | # Anything higher than this threshold will be marked as toxic and commented on
50 | sentimentBotToxicityThreshold: .7
51 |
52 | # *Required* Comment to reply with
53 | sentimentBotReplyComment: >
54 | Please be respectful of other users.
55 |
56 | # Note: the bot will only work if your repository has a Code of Conduct
57 |
--------------------------------------------------------------------------------
/guides/people-operations/team-trips.md:
--------------------------------------------------------------------------------
1 | # Team Trips
2 |
3 | A team that meets together, stays together.
4 | Remote working does not mean working in isolation – we meet up with the rest of the team several times a year at spectacular locations,
5 | from exotic islands in Thailand to the breathtaking mountains of Patagonia in Argentina.
6 |
7 | “Ideas are worthless without execution” — that means we should maximize effect of our team-trips.
8 | To achieve that, we have a simple guide to use while working on the team trips.
9 |
10 | ## How to get the most out of the team trip
11 |
12 | Most of the time, we have daily work sessions to define the future of the IxDF.
13 | Human brains are unreliable when it comes to remember something in detail; that’s why we need the ideas written down as soon as they are discussed.
14 | After the team trip, we are going to execute over those ideas.
15 |
16 | ### 1. Using GitHub to make action plans
17 |
18 | GitHub is the IxDF’s main project management tool. We will be using [🔒 IxDF-web's Issues](https://github.com/InteractionDesignFoundation/IxDF-web/issues) to make action plans for whatever we talk in and out of the work sessions during the trip.
19 | To create a new issue, you can simply click [IxDF-web/issues](https://github.com/InteractionDesignFoundation/IxDF-web/issues).
20 |
21 | Here is a screenshot of a new issue, briefly explaining how you can customize it:
22 |
23 |
24 |
25 | After you fill out the details, remember to click on **Submit new issue**. :-)
26 |
27 | ### 2. Applying SMART criteria for action plans
28 |
29 | When making action plans for the future of the IxDF, make sure that it fits to the [SMART criteria](https://en.wikipedia.org/wiki/SMART_criteria):
30 |
31 | **STRETCH GOAL:** Increase the traffic on the IxDF website.
32 |
33 | - **S**pecific: Increase the incoming traffic to the UX-daily article pages on the IxDF website.
34 | - **M**easureable: Increase the traffic on the IxDF website to 50,000 per day.
35 | - **A**ssignable: Increase the traffic on the IxDF website by expanding our social media reach through ads.
36 | - **R**ealistic: Increase the traffic on the IxDF website from 40,000 per day to 50,000 per day.
37 | - **T**ime-bound: Increase the traffic on the IxDF website within the next 2 months.
38 |
39 | **SMART GOAL:** Increase the incoming traffic to the UX-daily article pages on the IxDF website from 40,000 visitors per day to 50,000 per day by expanding our social media reach through ads within the next 2 months.
40 |
41 | There will be a correlation between the ease of execution and how well the action plan fits the SMART criteria. It might not be super easy to apply this criteria while discussing ideas, but we will have more time later to improve our action plans, and discuss them further.
42 |
43 | 🦄
44 |
--------------------------------------------------------------------------------
/library/backend/conventions--sql.md:
--------------------------------------------------------------------------------
1 | # IxDF's SQL conventions
2 |
3 | [[toc]]
4 |
5 | ## DATETIME vs TIMESTAMP vs biginteger
6 |
7 | **TL;DL: Use `DATETIME`** to store datetime values, and use `TIMESTAMP` to store metadata (such as when a record has been created, updated, or deleted).
8 |
9 | - DATETIME supported range '1000-01-01 00:00:00' to '9999-12-31 23:59:59'.
10 | - TIMESTAMP supported range '1970-01-01 00:00:01' UTC to '2038-01-19 03:14:07' UTC.”
11 |
12 | The default behavior for default values of timestamps in MySQL and/or MariaDB differs for the first timestamp declaration compared to subsequent timestamps:
13 |
14 | > If the explicit_defaults_for_timestamp system variable is disabled, the first TIMESTAMP column has both DEFAULT CURRENT_TIMESTAMP and ON UPDATE CURRENT_TIMESTAMP if neither is specified explicitly.
15 |
16 | See [MySQL 5.7 Reference Manual](https://dev.mysql.com/doc/refman/5.7/en/timestamp-initialization.html) for more details.
17 | Note, `explicit_defaults_for_timestamp` is disabled by default.
18 |
19 | When we read DATETIME, we should always be aware about timezone, at least we should be sure that DATETIME uses a timezone you expect to receive.
20 |
21 | Let’s review a common edge case: daylight saving. On the same day, it’s possible to have the same time twice,
22 | and when you compare times, you should understand which time is greater. TIMESTAMP provides this opportunity, DATETIME not.
23 |
24 | 1. Sunday, 7 November 2021, 02:00:00 clocks are turned backward 1 hour to:
25 | 2. Sunday, 7 November 2021, 01:00:00 local standard time instead.
26 |
27 | As you can see, there are 01:00:00 2 times at the same day.
28 |
29 | ### biginteger and year 2038 problem
30 |
31 | [Year 2038 problem](https://en.wikipedia.org/wiki/Year_2038_problem) caused by the limitations of signed 32-bit integer
32 | that used to store timestamps in a lot of popular DB engines (including MySQL).
33 | The latest possible date is `03:14:07 UTC on 19 January 2038` ((2^31)-1 = 2,147,483,647 seconds after 1 January 1970).
34 |
35 | Should we care about this problem? — Yes and no. Currently, we don’t have any data-flows and requirements to store any
36 | info in DB with dates close to 2038 year (it’s possible to try to create a Meetup far in the future, not it’s not critical).
37 | Current possible option is to use `unsigned biginteger` (2^64 - 1) date type.
38 | But we expect that closer to 2035 a lot of companies will start to work on this problem, we’ll have more solutions and options
39 | to deal with it, so we decided to postpone solving this problem.
40 |
41 | ## Coding style
42 |
43 | Use an upper case for SQL keywords and functions:
44 |
45 | ```sql
46 | # GOOD
47 | SELECT MAX(sent_at) last_sent_at, notification_class FROM notification__notification_log GROUP BY notification_class
48 |
49 | # BAD
50 | select max(sent_at) last_sent_at, notification_class from notification__notification_log group by notification_class
51 | ```
52 |
53 | 🦄
54 |
--------------------------------------------------------------------------------
/.vitepress/config.mts:
--------------------------------------------------------------------------------
1 | import {defineConfig} from 'vitepress';
2 | import {withMermaid} from 'vitepress-plugin-mermaid';
3 | import {generateSidebar} from 'vitepress-sidebar';
4 |
5 | // https://vitepress.dev/reference/site-config
6 | const config = defineConfig({
7 | lang: 'en-US',
8 | title: 'IxDF Open Handbook',
9 | description: 'Handbook and guidelines for IxDF technical staff.',
10 | head: [
11 | ['link', {rel: 'icon', href: '/favicons/favicon.ico'}],
12 | ['link', {rel: 'apple-touch-icon', href: '/favicons/apple-touch-icon.png'}],
13 | ['link', {rel: 'stylesheet', href: 'https://fonts.googleapis.com/css?family=Merriweather:400,400i,700|Source+Code+Pro|Source+Sans+Pro:400,400i,700&display=swap'}],
14 | ],
15 | themeConfig: {
16 | // https://vitepress.dev/reference/default-theme-config
17 | siteTitle: 'IxDF Open Handbook',
18 | editLink: {
19 | pattern: 'https://github.com/InteractionDesignFoundation/handbook/edit/main/:path',
20 | text: 'Edit this page on GitHub',
21 | },
22 | lastUpdated: {text: 'Last Updated'},
23 | search: {
24 | provider: 'local',
25 | },
26 | logo: 'https://public-images.interaction-design.org/ixdf-brand/ixdf-logo.svg',
27 | nav: [
28 | {text: 'IxDF Handbook', link: '/'},
29 | {text: "🔐 Development Docs", link: "https://docs.information-architecture.org"},
30 | {text: 'UI Kit', link: 'https://ui-kit.interaction-design.org/'},
31 | {text: 'We\'re hiring!', link: 'https://www.interaction-design.org/about/careers'},
32 | ],
33 |
34 | // see https://github.com/jooy2/vitepress-sidebar
35 | sidebar: generateSidebar({
36 | useTitleFromFileHeading: true,
37 | capitalizeFirst: true,
38 | hyphenToSpace: true,
39 | collapseDepth: 1,
40 | excludeFiles: [
41 | 'README.md',
42 | 'CONTRIBUTING.md',
43 | ],
44 | excludeFolders: [
45 | 'node_modules',
46 | 'development',
47 | 'outdated',
48 | ],
49 | }),
50 | },
51 |
52 | markdown: {
53 | lineNumbers: false,
54 |
55 | // options for @mdit-vue/plugin-toc
56 | // https://github.com/mdit-vue/mdit-vue/tree/main/packages/plugin-toc#options
57 | toc: {level: [2, 3]},
58 | },
59 |
60 | ignoreDeadLinks: [
61 | /\.neon/,
62 | /\.php/,
63 | /ocramius/,
64 | ],
65 | appearance: false // This disables the dark mode toggle
66 | });
67 |
68 | // eslint-disable-next-line import/no-default-export
69 | export default withMermaid({
70 | ...config,
71 | // optionally, you can pass MermaidConfig
72 | mermaid: {
73 | // refer https://mermaid.js.org/config/setup/modules/mermaidAPI.html#mermaidapi-configuration-defaults for options
74 | },
75 | });
76 |
--------------------------------------------------------------------------------
/library/frontend/conventions--css.md:
--------------------------------------------------------------------------------
1 | # IxDF's CSS conventions
2 |
3 | [[toc]]
4 |
5 | ## PostCSS
6 |
7 | We use `postcss-preset-env` and CSS features from [stage 3+](https://preset-env.cssdb.org/features#stage-3).
8 |
9 | ### Reduce the cognitive load
10 |
11 | - Use as many native CSS features as possible;
12 | - SHOULD not use PostCSS magic like `&` (exceptions: pseudo-elements and pseudo-classes and `@media` rules);
13 | - SHOULD not use nesting, because BEM names are unique enough (exceptions: pseudo-elements and pseudo-classes and `@media` rules);
14 |
15 | ## CSS Class Naming conventions
16 |
17 | We use [ITCSS](http://www.creativebloq.com/web-design/manage-large-css-projects-itcss-101517528): superset of
18 | [BEM](http://getbem.com/introduction/) CSS methodology.
19 |
20 | - [ITCSS architecture](https://www.xfive.co/blog/itcss-scalable-maintainable-css-architecture/)
21 | - [ITCSS: Harry Roberts - Managing CSS Projects with ITCSS (video)](https://youtu.be/1OKZOV-iLj4?t=404)
22 | - [BEM quick-start](https://en.bem.info/methodology/quick-start)
23 | - [Battling BEM CSS: 10 Common Problems And How To Avoid Them](https://www.smashingmagazine.com/2016/06/battling-bem-extended-edition-common-problems-and-how-to-avoid-them/)
24 |
25 | Additionally, we prefer to use camelCase, as follows:
26 |
27 | ```css
28 | .blockName {
29 | }
30 | .blockName__elementName {
31 | }
32 | .blockName__elementName--modifierName {
33 | }
34 | ```
35 |
36 | ## Utility classes
37 |
38 | Along with our BEM-based classes, we have our utility classes. For all components and page specific classes we use BEM but when it comes to utility classes we have chosen to follow [Tailwind 3](https://tailwindcss.com/). This makes it easier for any new developer to come in to our project and know classnames without even having to go through our docs. Examples of utility classes
39 |
40 | ```html
41 |
42 |
43 |
44 |
45 | ```
46 |
47 | ### Using utility classes
48 |
49 | Whenever a function can be performed using utility classes, then the utility class should be used instead of creating custom BEM classes. One of the most common example is margin and padding utility classes that are needed in almost every page.
50 |
51 | ```html
52 |
53 |
54 |
55 |
56 | ```
57 |
58 | ### Using BEM along with utility classes
59 |
60 | Sometimes a page will require its custom CSS, and in that case, it is good to combine utility classes along with the BEM bases classes for the page/component.
61 |
62 | ```html
63 |
64 |
65 |
66 | ```
67 |
68 | This [article](https://css-tricks.com/building-a-scalable-css-architecture-with-bem-and-utility-classes/) provides excellent guidelines for using BEM, utility classes and using them together.
69 |
70 | ## Files naming conventions
71 |
72 | Filenames should also use BEM + camelCase notation (same naming conventions above for CSS/PostCSS). The file structure for
73 | a CSS component would look like this:
74 |
75 | ```
76 | /components
77 | /inputGroup
78 | inputGroup.css
79 | inputGroup--small.css
80 | inputGroup--big.css
81 | inputGroup.md
82 | . . .
83 | ```
84 |
--------------------------------------------------------------------------------
/guides/roles/senior-developer.md:
--------------------------------------------------------------------------------
1 | # Expectations from Developers
2 |
3 | We are a small team of senior developers, and the IxDF does not employ junior or medium level developers.
4 | That’s why this list only includes our expectations for senior developers.
5 |
6 | ## Senior developer
7 |
8 | 1. A senior developer understands and is aligned with the IxDF Company Culture which is **very** thoroughly explained in our "IxDF Company Culture Course" (taken during your onboarding phase).
9 | 1. **Seriousness firstly means "responsibility"**. Responsibility for your decisions, solutions, code, and communication with the team.
10 | 1. A senior developer is [able to carry a message to Garcia](https://courses.csail.mit.edu/6.803/pdf/hubbard1899.pdf):
11 | They **can take the initiative** when carrying out a challenging assignment.
12 | 1. A senior developer **has experience**; because they are able to learn from their mistakes.
13 | 1. A senior developer **helps their team get better every day**. E.g. by energizing his/her colleagues on group calls, setting an example of awesome code that awes the rest of the team, inspiring colleagues with his/her results/help, etc. etc.
14 | 1. A senior developer **finds and fixes the root causes of the problem** and not just the symptoms.
15 | 1. A senior developer can **self-reliantly deliver working software**.
16 | 1. A senior developer understands that their job is to **provide solutions to problems**, not to write code.
17 | 1. A senior developer [**knows their tools**](https://stitcher.io/blog/craftsmen-know-their-tools): IDE, OS/terminal, debugging, static analyzers, formatters, test frameworks, CI, CD, etc.
18 | 1. A senior developer **knows how to choose the right tool and framework**.
19 | 1. A senior developer actively employs the Boyscout principle and helps update this documentation ("always leave the campground cleaner than you found it")
20 | 1. **Most importantly**, a senior developer reminds us all, or reminds a given individual developer, when we do not live up to what’s written on this page, written in the [IxDF Zen Code](../../outdated/development/README.md#the-ixdf-zen-code), taught in the IxDF Culture Course, or considered a best practice among senior developers. A senior developer is thus a "guarantor" that we continually optimize our team spirit, fun, productivity, learning, results, impact on the world, and programming practices.
21 |
22 | ### Senior backend developer
23 |
24 | This list is an extension of our expectations from a senior developer (see the previous section).
25 |
26 | 1. Broad and extensive knowledge of the software development process and its technologies.
27 | 1. Strong understanding of the primary programming language used in IxDF.
28 | 1. Experience in using object-oriented design principles and patterns.
29 |
30 | ### Senior frontend developer
31 |
32 | This list is an extension of our expectations from a senior developer (see the previous section).
33 |
34 | 1. Strong knowledge of HTML and at least one modern JS framework and an understanding of how it works.
35 | 1. Middle-level knowledge of at least one different JS framework OR strong understanding of design patterns.
36 |
37 | ## Short articles to read
38 |
39 | Now, please read the following articles:
40 |
41 | 1. [So You Want To Be a Senior Developer?](https://css-tricks.com/want-senior-developer/)
42 | 1. [The Role of a Senior Developer](https://web.archive.org/web/20160609115315/http://mattbriggs.net/blog/2015/06/01/the-role-of-a-senior-developer/)
43 |
44 | 🦄
45 |
--------------------------------------------------------------------------------
/library/backend/literature.md:
--------------------------------------------------------------------------------
1 | # IxDF's Literature for back-end developers
2 |
3 | > You are reading this [...] for two reasons. First, you are a programmer. Second, you want to be a better programmer. Good. We need better programmers.
4 | >
5 | > -Robert C. Martin (from Clean Code)
6 |
7 | We have, again and again, experienced that it’s not enough to be a good developer — let alone be a developer. We also have
8 | experienced in our team that once a developer has studied the correct content, the code quality and the collective peace of mind
9 | have multiplied. That’s why we have curated a great deal of material for ourselves to become better.
10 |
11 | > The frenetic rate of change in our industry means that software developers must continue to learn copious quantities just to keep up.
12 | > Woe to the architects who stop coding—they will rapidly find themselves irrelevant. Woe to the programmers who stop learning new
13 | > languages—they will watch as the industry passes them by. Woe to the developers who fail to learn new disciplines and techniques—their
14 | > peers will excel as they decline.
15 | >
16 | > -Robert C. Martin (from Clean _Coder_)
17 |
18 | ## Index
19 |
20 | You can find all books, articles and videos on the shared folder `IxDF - Shared Reading - Library of Dev literature`.
21 |
22 | ### Reading list
23 |
24 | 1. Classic programming (books): `Robert Martin - Clean Code - 2008` and/or `Steve McConnell - Code Complete, 2nd edition - 2014`.
25 | 1. Framework: Official Laravel [documentation](https://laravel.com/docs/) :smile:
26 | 1. Design Patterns (book): `Erich Gamma, Richard Helm, Ralph Johnson, John M. Vlissides - Design Patterns - 1994` , `Eric Freeman - Head First Design Patterns - 2004`, or [Dive Into design patterns](https://refactoring.guru/design-patterns/book)
27 | 1. Server management (book): `Chris Fidao - Servers for Hackers - 2016.pdf`.
28 | 1. Clean Architecture (book): `Robert Martin - Clean Architecture: A Craftsman's Guide to Software Structure and Design - 2017`.
29 | 1. Topic:
30 | [S](https://code.tutsplus.com/tutorials/solid-part-1-the-single-responsibility-principle--net-36074).
31 | [O](https://code.tutsplus.com/tutorials/solid-part-2-the-openclosed-principle--net-36600).
32 | [L](https://code.tutsplus.com/tutorials/solid-part-3-liskov-substitution-interface-segregation-principles--net-36710).
33 | [I](https://code.tutsplus.com/tutorials/solid-part-4-the-dependency-inversion-principle--net-36872).
34 | [D](https://code.tutsplus.com/tutorials/solid-part-4-the-dependency-inversion-principle--net-36872).
35 | principles ([short version](https://jokiruiz.com/software/solid-principles-php/)). There are also videos on the topic inside `SOLID Principles in PHP` directory.
36 | 1. Topic:
37 | [KISS, YAGNI & DRY Principles](https://code.tutsplus.com/tutorials/3-key-software-principles-you-must-understand--net-25161).
38 | 1. Optional: TDD in Laravel: [`Course videos for Test-Driven Laravel`](https://course.testdrivenlaravel.com/) video course.
39 | 1. Optional: Classic programming (book): `Hunt A., Thomas D. - The Pragmatic Programmer. From Journeyman to Master - 1999`.
40 | 1. Optional: DDD (book): `Vernon V. - Domain-Driven Design Distilled - 2016`.
41 | 1. Optional: Articles inside `Articles` shared folder.
42 |
43 | ## Subscriptions
44 |
45 | Subscriptions are a great way to keep up with the latest news and trends in the industry. Here are some of the best ones:
46 |
47 | Newsletters:
48 |
49 | 1. [PHP Annotated Monthly](https://blog.jetbrains.com/phpstorm/tag/php-annotated-monthly/) digests by JetBrains
50 | 1. [Laravel news weekly newsletter](https://laravel-news.com/newsletter)
51 |
52 | YouTube:
53 |
54 | 1. [Laracon EU](https://www.youtube.com/channel/UCb9XEo_1SDNR8Ucpbktrg5A) annual Laravel conference videos on YouTube.
55 | 1. [PHP UK Conference](https://www.youtube.com/@phpukconference/videos)
56 | 1. [PHP Annotated](https://www.youtube.com/@phpannotated/videos) by JetBrains
57 |
58 | Blogs:
59 |
60 | 1. Freek’s (from Spatie) blog on Laravel & PHP: [freek.dev](https://freek.dev)
61 | 1. Brent’s Roose blog on Laravel & PHP: [stitcher.io](https://stitcher.io/blog)
62 | 1. Tim MacDonald blog: [timacdonald.me](https://timacdonald.me/)
63 |
64 | ## References
65 |
66 | 1. [Clean Code concepts adapted for PHP](clean-code-php.md)
67 | 1. [IxDF’s back-end conventions](README.md)
68 |
69 | 🦄
70 |
--------------------------------------------------------------------------------
/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | # https://vitepress.dev/reference/default-theme-home-page
3 | layout: home
4 |
5 | hero:
6 | name: 'IxDF Open Handbook'
7 | tagline: 'Open handbook for developers (Laravel+JS) created by the IxDF tech team.'
8 | actions:
9 | - theme: ghost
10 | text: Start here
11 | link: /README.md
12 | - theme: ghost
13 | text: Backend dev docs
14 | link: /library/backend/README.md
15 | - theme: ghost
16 | text: Frontend dev docs
17 | link: /library/frontend/README.md
18 | ---
19 |
20 |
21 |
IxDF Zen Code
22 |
23 |
24 |
Development
25 |
26 |
Explicit is better than implicit.
27 |
Delegate work to tool when possible.
28 |
Simple is better than complex.
29 |
Complex is better than complicated.
30 |
Flat is better than nested.
31 |
Errors should never pass silently.
32 |
There should be one (and preferably only one) obvious way to do it.
33 |
It should be easy to do run popular actions.
34 |
Bad stuff should be difficult to do.
35 |
If the implementation is hard to explain, it's a bad idea.
36 |
If the implementation is easy to explain, it may be a good idea.
37 |
38 |
Team
39 |
40 |
We celebrate our achievements and encourage everyone to contribute.
41 |
We all have decision-making authority, and everyone in the team is committed to each other's success.
42 |
We have a flat hierarchy; everyone does everything possible to never fail one another.
43 |
We don't punish anyone for making mistakes.
44 |
We care about communication; we believe the "how" in communication is as important as the "what".
45 |
46 |
47 |
48 |
Productivity
49 |
50 |
We believe motivation and productivity come naturally when you work on something you're passionate about.
51 |
We are action-oriented and strong believers in the maxim "ideas are worthless without execution."
52 |
We have enormous degrees of freedom because we are able to live up to that responsibility.
53 |
We finish what we have started; we don't feel good until we've carved a unicorn out of the monster.
54 |
We know that even small tasks can give us emotional rewards when we know why we are doing them.
55 |
We set audacious but achievable goals by breaking them into small and concrete plans.
56 |
We welcome critique; we use our mistakes in a constructive way to become stronger.
57 |
58 |
Community
59 |
60 |
We exist, because our community exists.
61 |
Our codebase reflects the high expectations of our community.
62 |
We constantly reshape our platform and codebase based on our community's needs.
63 |
We believe our platform and community will make the world a better place.
77 |
78 |
--------------------------------------------------------------------------------
/guides/collaboration-tools.md:
--------------------------------------------------------------------------------
1 | # Collaboration tools
2 |
3 | Collaboration is a keystone in IxDF’s success, and we couldn't make it happen without the right tools and processes.
4 | These are the tools we use almost every day.
5 |
6 | Please note that you should be using your company email address with all the tools listed below (except probably GitHub).
7 |
8 | ## [GitHub](https://github.com/InteractionDesignFoundation)
9 |
10 | Our issue tacker and code storage. [GitHub Actions](https://github.com/features/actions) is our CI/CD.
11 |
12 | Usage of [2FA](https://github.com/settings/security) is required. We also use real face photos for a profile picture to look more friendly to your colleagues.
13 |
14 | ## [Asana](https://app.asana.com/)
15 |
16 | Developers collaborate with other teams here. This is the main task tracker and project management tools for non-dev teams.
17 | Use your Google account to join the company on Asana.
18 |
19 | ## [Slack](https://slack.com/download)
20 |
21 | We use [Slack](https://slack.com/download) as our main tool for written communication and important notifications.
22 | Unless you're deep in the flow (state), you should be paying attention to what’s going on there.
23 |
24 | We also use real face photos for a profile picture to look more friendly to your colleagues.
25 |
26 | ### Do Not Disturb Hours
27 |
28 | Slack now supports "Do Not Disturb Hours" so you won’t be pinged in the middle of the night or while you are dealing with family matters.
29 | You can set your "Do Not Disturb Hours" by clicking on the bell at the top of the left pane in the Slack app.
30 | You also have the option of snoozing for 20 minutes or up to 24 hours.
31 |
32 | ## [Zoom](https://zoom.us)
33 |
34 | Zoom is our preferred tool to take video calls. To set up a Zoom meeting, [sign up for a free basic account](https://zoom.us/signup) using your IxDF team email address, and share the link for your "personal meeting room" with your participants.
35 | Note that on the Basic license, meetings are capped at 100 people, and meeting durations are capped at 40 minutes.
36 |
37 | ## [Google Calendar](https://calendar.google.com)
38 |
39 | We use Google Calendar to share info about our events: meetings, call, team-trips, etc.
40 |
41 | Recommendation: consider to have 2 different calendars on your IxDF google account: **public** and **private**.
42 |
43 | There are several benefits and reasons to sharing your calendar with everyone at IxDF:
44 |
45 | 1. Transparency is one of our values and sharing what you work on is in line with our message of "be open about as many things as possible".
46 | 1. Due to our timezone differences, there are small windows of time when our availabilities overlap.
47 | If other members need to schedule a new meeting, seeing the details of recurring meetings (such as 1-1s) will
48 | allow for more flexibility in scheduling without needing to wait for a confirmation from the team member.
49 | This speaks to our value to be more efficient.
50 |
51 | ### Modifying Events
52 |
53 | Please click 'Guests can modify event' so people can update the time in the calendar instead of having to reach out via other channels.
54 | You can configure this to be checked by default under [Event Settings](https://calendar.google.com/calendar/b/1/r/settings).
55 |
56 | 
57 |
58 | ## [Dropbox](https://www.dropbox.com/)
59 |
60 | We need a secure way of sharing files, and [Dropbox](https://www.dropbox.com/) is one of the best tools out there for this purpose.
61 | Via Dropbox you will get access to our literature library, exported designs and pretty much any other file you need to do your work.
62 |
63 | When you see the phrase "shared folders", we mean the "shared folders" on Dropbox.
64 |
65 | ## [Figma](https://figma.com)
66 |
67 | We also use Figma(https://figma.com) to share designs. Ask for an invitation in case you need to access anything on Figma.
68 |
69 | ## [LastPass](https://www.lastpass.com)
70 |
71 | We use LastPass to share login credentials, API keys and some top secret information. :-)
72 |
73 | ## [Downnotifier](https://downnotifier.com/)
74 |
75 | Sends an alert when your website is down (via SMS).
76 | **Please [add your cell phone number](https://www.downnotifier.com/list/edit?id=628289) to receive text messages in case of emergency**.
77 |
78 | ## Ye Olde Email
79 |
80 | Yeah, we still use email (and pigeons) from time to time, but make sure to check your email after pushing a new change
81 | since you will receive a notification in case the build (CI) fails.
82 | To make email less dull, we ask new team members to upload their most handsome/beautiful picture with a big smile!
83 |
84 | Also, please ensure that you have easy access to check your company email inbox (consider installing a browser extension such as
85 | [Chrome](https://chrome.google.com/webstore/detail/notifier-for-gmail/dcjichoefijpinlfnjghokpkojhlhkgl?hl=en),
86 | [Firefox](https://addons.mozilla.org/en-US/firefox/addon/gmail-notifier-restartless/),
87 | [Safari](https://safari-extensions.apple.com/details/?id=com.add0n.simple-notifier-RED8XKG2R4)
88 | or use mail client).
89 |
90 | 🦄
91 |
--------------------------------------------------------------------------------
/guides/OKR/04-stay-aligned-as-a-team.md:
--------------------------------------------------------------------------------
1 | # Stay Aligned as a Team
2 |
3 | To make the OKR process work, we have to stay aligned as a team every day, week and month.
4 | At the IxDF, we use two-week Sprints to plan and execute our tasks.
5 | Each Sprint begins with a planning meeting.
6 |
7 | ## Prepare Yourself for a Sprint Planning Meeting
8 |
9 | 
10 |
11 | _Note: We use Agile/Scrum in all our teams. It’s really just a fancy word for something simple so don’t be scared about the terminology or think you need to read books about it. There is some background information on how the Dev Team uses Scrum [here](https://handbook.interaction-design.org/development/guides/scrum/)._
12 |
13 | Prepare yourself before a Sprint Planning Meeting
14 |
15 | 1. Go to the Spreadsheet “IxDF OKR Planning.xlsx” in the folder [IxDF / IxDF - PeopleAndCulture - Job Roles and Organizational Structure](https://www.dropbox.com/home/IxDF%20-%20PeopleAndCulture%20-%20Job%20Roles%20and%20Organizational%20Structure) on our DropBox instance—Available only to IxDF team members.
16 | 2. If this is your first time, then please CAREFULLY STUDY the tab “Sprint Planning Template” – and read all the “help bubbles”.
17 | 3. Find the tab in the spreadsheet called “Sprint Planning Team XYZ” where “XYZ” is your Team.
18 | 4. If that tab doesn’t exist, then create a copy of the tab “Sprint Planning Template” can call it “Sprint Planning Team XYZ” where “XYZ” is your Team.
19 | 5. Start editing/adding your tasks based on the instructions in the “help bubbles”
20 |
21 | ## Hold a Sprint Planning Meeting
22 |
23 | 
24 |
25 | **Attendees**: All Team Members in a Team. The Team Lead acts in the role of “Scrum Master”.
26 |
27 | **Periodicity**: Bi-weekly (every 2 weeks) in the week where the “OKR Check-in Meeting” is NOT held.
28 |
29 | **Duration**: 5-20 minutes per person – or 2 hour maximum for the whole team.
30 |
31 | **Important**: Keep the meeting full of energy and ambition. Don’t speak slowly or go into too much detail unless it’s relevant to others. Everyone should leave the meeting excited – not drained!
32 |
33 | **Purpose**: Have a clean, balanced, exciting, and ambitious plan of significant tasks / to dos for the coming 2 weeks.
34 |
35 | Hold the Sprint Planning Meeting
36 |
37 | - The Team Lead says welcome and reminds everyone that:
38 | - The meeting should be full of energy and ambition – not drain our energy.
39 | - “You get out what you put in”. Work is like any other aspect of life: The more energy and ambition you put into it, the more it will give back. Positivity, energy, excitement are intentional states of mind…. and this meeting is your chance to add that your work life.
40 | - Preparation is key and everyone needs to prepare thoroughly before these meetings: If not, the meetings will be “yada yada” and drain everyone’s energy.
41 | - Everyone takes turns and presents their Sprint Planning.
42 | - Share your screen so you can point at the item you are talking about
43 | - At the end of the meeting, everyone will have visibility into what their Team Members are doing. We will we able to move forward like a Team of Leaders.
44 |
45 | ## Do a Daily Standup
46 |
47 | 
48 |
49 | “Daily standups” are – in Scrum/Agile Terminology – a daily meeting in the morning where all Team Members give a short update on 3 key things:
50 |
51 | 1. What have you **accomplished** since last meeting?
52 | 2. What are your **plans** for today?
53 | 3. Is anything **blocking** you?
54 |
55 | Because we value concentration time so much, we’ve decided to skip the Daily Standup meetings – and then use the [#daily-updates](https://interaction-design.slack.com/archives/CPRN9JWHK) channel on Slack instead.
56 |
57 | This will only as long as everyone consistently remembers to submit their updates at the end (or beginning) of their work day.
58 |
59 | ## Prepare for Bi-Weekly OKR 1:1 Check-in Meeting
60 |
61 | 
62 |
63 | All the weeks where there is NOT a Sprint Planning meeting, you hold a “1:1 OKR Check-In” with your Team Lead.
64 | This is your chance to get a good, relationship-building conversation with your Team Lead and to report progress on your OKRs.
65 | This is how you prepare:
66 |
67 | - For each Key Result you own you make an update in our OKR spreadsheet. That way, we all head into our OKR meetings with a fully updated OKR spreadsheet.
68 | - [add more things to do as preparation here, e.g. questions to ask yourself]
69 |
70 | ## Hold the Bi-Weekly Team-wide OKR Check-in Meeting
71 |
72 | 
73 |
74 | _Held bi-weekly, i.e. on the weeks where there is NOT a Sprint Planning meeting, right after the 1:1 Check-ins_
75 |
76 | After the Team Lead has had a round 1:1 OKR check-ins, it’s time for the Team-wide OKR Check-in Meeting.
77 |
78 | This Team-wide meeting could be the day after the 1:1 Meetings or on the same day. Just make sure that you
79 |
80 | If you already have a recurring Team-wide meeting, then hold this “Team-wide OKR Check-in Meeting” at the same time. There’s no reason for having too many meetings.
81 |
82 | At the end of the quarter, it is time to [assess your OKRs](./05-assess-your-okrs).
83 |
--------------------------------------------------------------------------------
/guides/onboarding/README.md:
--------------------------------------------------------------------------------
1 | # Onboarding
2 |
3 | Welcome aboard!
4 |
5 | We know you’re amazing because you’re here (otherwise, you wouldn’t be here).
6 | Congrats: You've landed one of the greatest jobs in the world! 🎉
7 |
8 | 
9 |
10 | Now it’s time to get you up to speed with all the things you need to know
11 | about your role at the IxDF and your day-to-day work as a developer.
12 |
13 | Before you start, please ensure that you know your mentor (onboarding buddy)
14 | to make your onboarding process smooth and easy.
15 |
16 | ## Contribute to our documents
17 |
18 | From here on, you will read a lot of documents in different places. Your first
19 | contribution to IxDF is to help us make those documents as perfect as humanly possible
20 | and your fresh look is invaluable.
21 | We don't expect you to spend too much time and feel pressured, however you can:
22 |
23 | 1. Fix broken links, invalid/obsolete statements, typos, incorrect instructions, etc.
24 | Don't be afraid to commit your changes 🙂
25 | 1. Share your feedback with your onboarding buddy
26 |
27 | ## Plan
28 |
29 | 1. To start, head over to [🔒 IxDF Handbook Course](https://www.interaction-design.org/courses/ixdf-handbook)
30 | and go through Lesson 1 and Lesson 2 where the onboarding is explained.
31 | 1. Set up and know your [collaboration tools](../collaboration-tools.md).
32 | 1. Know our [expectations from you and your work](../roles/senior-developer).
33 | 1. Get closer to coding: Setup your [🔒 working environment](https://github.com/InteractionDesignFoundation/IxDF-web/blob/main/docs/environment/first-run/README.md)
34 | (private repository link) — It’s time-consuming (2-3 hours), so don't wait.
35 | While your tools are being downloaded/installed, you can continue with the list.
36 | 1. Never stop learning 📖. Go through our library and create a plan to acquire
37 | every bit of knowledge there. Once you have a plan, please discuss it with
38 | your mentor. (Are you full-stack? Then please open both links☀):
39 | - Literature/subscriptions [for back-end developers](../../library/backend/literature)
40 | - Literature/subscriptions [for front-end developers](../../library/frontend/literature)
41 | 1. If you have any issues accessing the platform, company culture course
42 | or our collaboration tools, please ping the Member Experience team (`@member-experience-team`)
43 | via Slack (#onboarding-buddy-chat), so they can assist you. By this point,
44 | you should have already completed lesson 0 of the IxDF Onboarding & Company Culture course,
45 | so now you may continue with the rest of the lessons.
46 | 1. Go through our guides:
47 | 1. [Scrum](../../outdated/scrum/README.md)
48 | 1. [🔒 Git Flow](https://github.com/InteractionDesignFoundation/IxDF-web/blob/main/docs/workflows/git-flow.md)
49 | 1. Setup Xdebug
50 | 1. [How to get domain knowledge](onboarding--domain-knowledge.md)
51 | 1. Coding (finally! 🎉)
52 | 1. [🔒 File-naming conventions](https://github.com/InteractionDesignFoundation/IxDF-web/blob/main/docs/code/naming-conventions.md)
53 | 1. [🔒 Contributing standards](https://github.com/InteractionDesignFoundation/IxDF-web/blob/main/CONTRIBUTING.md)
54 | 1. [🔒 Platform glossary](https://github.com/InteractionDesignFoundation/IxDF-web/blob/main/docs/glossary.md)
55 | 1. Architecture (Are you full-stack? You know what to do 😊)
56 | - [🔒 Backend](https://github.com/InteractionDesignFoundation/IxDF-web/blob/main/docs/code/backend/architecture.md)
57 | - [🔒 Frontend](https://github.com/InteractionDesignFoundation/IxDF-web/blob/main/docs/code/frontend/architecture.md)
58 | 1. [🔒 Setup your IDE](https://github.com/InteractionDesignFoundation/IxDF-web/blob/main/docs/environment/IDE/README.md)
59 | for the project.
60 |
61 | Happy reading/hacking!
62 |
63 | ## What’s next?
64 |
65 | Are you ready for new challenges? Great!
66 |
67 | Your onboarding buddy should prepare a number of tasks for your smooth onboarding
68 | to the codebase. You will be assigned to your first GitHub issues, make your first
69 | contribution to our codebase, and create your first PR — a lot of exciting stuff!
70 |
71 | Your first GitHub issues will be tasks that take you through some [core sub-systems](https://docs.information-architecture.org/domain/systems-and-code-owners.html)
72 | of our codebase. That will give you a better overview of what these sub-systems
73 | do and the state of the code within each sub-system (e.g. what’s the amount of
74 | technical debt versus up-to-date code in a given system). Don’t be alarmed if some
75 | of the issues will lead you into areas of the codebase where you find technical-debt
76 | or spaghetti code. That’s intentional, so you get exposed to both great code and technical debt.
77 |
78 | May the Force be with you!
79 |
80 | ## Provide feedback and present your progress
81 |
82 | In a few weeks, you’ll have a chance to look back at your progress within the IxDF.
83 | The entire development team will be very excited to hear your feedback. You'll meet
84 | very often with your onboarding buddy, so you'll have a good opportunity to ask
85 | for directions, and new issues, get answers for your questions, and get feedback.
86 | Here's a list of things you can share with your onboarding buddy or your colleagues:
87 |
88 | - Coding: What have you finished and deployed to production that is now used by hundreds or thousands of people?
89 | - Learning: What is your progress on consuming our library? Do you find them effective?
90 | - Domain: What have you learned about the IxDF and our platform?
91 | How can you help improve the most critical parts of our platform?
92 | - Culture: Can you list our vision, mission, and core values? What can you do to
93 | help IxDF accomplish its audacious goals?
94 |
95 | 🦄
96 |
--------------------------------------------------------------------------------
/library/frontend/conventions--js.md:
--------------------------------------------------------------------------------
1 | # IxDF's JavaScript Conventions
2 |
3 | This document extends
4 | [Clean code principles for JavaScript](clean-code-js.md).
5 |
6 | [[toc]]
7 |
8 | ## Browser support
9 |
10 | Support evergreen browsers only, usually all versions released latest 3 years (depends on info from Google Analytics).
11 |
12 | ## Code style
13 |
14 | Our code-styling rules are based on `eslint:recommended` rules.
15 | We also use some ESLint plugins to extend these rules.
16 | You can check all our custom rules at the [.eslintrc.js](https://github.com/InteractionDesignFoundation/IxDF-web/blob/main/.eslintrc.js) file.
17 |
18 | ## Docblocks
19 |
20 | [Use JSDoc](conventions--js) together with type definitions files.
21 | It will help both your IDE and developers to check types.
22 | This provides main benefits from TypeScript, but without translation cost and improved readability.
23 |
24 | Example:
25 |
26 | ```js
27 | // file: userAuthPolicy.js
28 | /**
29 | * @typedef {import('./user.d.ts').User} User
30 | */
31 |
32 | /**
33 | * @param {User} user
34 | * @returns {boolean}
35 | */
36 | function isAdmin(user) {
37 | return user.roles.includes('admin');
38 | }
39 | ```
40 |
41 | ```ts
42 | // file: user.d.ts
43 | export interface User {
44 | first_name: string;
45 | last_name: string;
46 | email: string;
47 | profil_image_url: string;
48 | roles: string[];
49 | }
50 | ```
51 |
52 | ## Explicit type definitions
53 |
54 | Use JSDoc and type checks in code to avoid errors like a null pointer: `TypeError: null is not an object`.
55 | If a variable type described as `@param {HTMLElement} element`,
56 | it should not contain `null` or `undefined` or other types.
57 | If the variable can contain a `null`, please describe it explicitly: `@param {HTMLElement|null} element`.
58 |
59 | ## Variable Names
60 |
61 | 1. Variable names generally shouldn’t be abbreviated.
62 | 1. You SHOULD use camelCase to name variables.
63 |
64 | ## Variable assignment
65 |
66 | Prefer `const` over `let`. Only use `let` to indicate that a variable will be reassigned. Never use `var`.
67 |
68 | ## Strict Comparisons
69 |
70 | Always use a triple equal to do variable comparisons. If you’re unsure of the type, cast it first.
71 |
72 | ```js
73 | // GOOD
74 | const one = 1;
75 | const another = '1';
76 |
77 | if (one === parseInt(another)) {
78 | // ...
79 | }
80 | ```
81 |
82 | ## Function keyword vs. arrow functions
83 |
84 | Function declarations should use the function keyword.
85 |
86 | ```js
87 | // GOOD
88 | function scrollTo(offset) {
89 | // ...
90 | }
91 |
92 | // BAD
93 | // Using an arrow function doesn’t provide any benefits here, while the
94 | // `function` keyword immediately makes it clear that this is a function.
95 | const scrollTo = (offset) => {
96 | // ...
97 | };
98 | ```
99 |
100 | Terse, single line functions may also use the arrow syntax. There’s no hard rule here.
101 |
102 | ```js
103 | // GOOD
104 | function sum(a, b) {
105 | return a + b;
106 | }
107 |
108 | // It’s a short and simple method, so squashing it to a one-liner is ok.
109 | const sum = (a, b) => a + b;
110 | ```
111 |
112 | Higher-order functions may use arrow functions if it improves readability.
113 |
114 | ```js
115 | function sum(a, b) {
116 | return a + b;
117 | }
118 |
119 | // GOOD
120 | const adder = (a) => (b) => sum(a, b);
121 |
122 | // OK, but unnecessarily noisy.
123 | function adder(a) {
124 | return function (b) {
125 | return sum(a, b);
126 | };
127 | }
128 | ```
129 |
130 | Anonymous functions should use arrow functions (Unless they need access to `this`).
131 |
132 | ```js
133 | ['a', 'b'].map((a) => a.toUpperCase());
134 | ```
135 |
136 | ## Object and array destructuring
137 |
138 | Destructuring is preferred over assigning variables to the corresponding keys.
139 |
140 | ```js
141 | // GOOD
142 | const [hours, minutes] = '12:00'.split(':');
143 |
144 | // BAD, unnecessarily verbose, and requires an extra assignment in this case.
145 | const time = '12:00'.split(':');
146 | const hours = time[0];
147 | const minutes = time[1];
148 | ```
149 |
150 | Destructuring is precious for passing around configuration-like objects.
151 |
152 | ## Promise
153 |
154 | We actively use `async/await` in our code.
155 | So for promises the recommended approach is to use async/await instead of `Promise.then()`.
156 | The Reason for using async/await is that it’s clean and has an easy-to-read syntax.
157 |
158 | ```js
159 | try {
160 | const response = await promiseToResolve();
161 | } catch (error) {
162 | log(error);
163 | }
164 | ```
165 |
166 | Or with our custom fetch promise
167 |
168 | ```js
169 | const response = await getHttpClient()
170 | .get('url')
171 | .catch((error) => log(error));
172 | if (response) {
173 | notify.success(response.message);
174 | }
175 | ```
176 |
177 | ## Interacting with the DOM
178 |
179 | Many times we will need to select DOM elements in our JS, there can be multiple approaches for getting the DOM element.
180 | But for consistency and clarity purposes, we SHOULD use data attributes as selectors.
181 |
182 | ```html
183 |
...
184 | ```
185 |
186 | ```js
187 | const cards = document.querySelectorAll('[data-course-card]');
188 | ```
189 |
190 | Unique elements should be selected by their `id` attribute:
191 |
192 | ```html
193 |
194 | ```
195 |
196 | ```js
197 | const subscribeForm = document.getElementById('subscribe-form');
198 | ```
199 |
200 | ## Back-end named routes
201 |
202 | Use `@route` annotations/comments to specify Laravel route names.
203 |
204 | Example: `@route 'api.course.enrollment.store'`.
205 | It solves a problem when we change the URL for a route on back-end (where we use named routes)
206 | but forget to change it in JS code (where we may hardcode it).
207 |
--------------------------------------------------------------------------------
/library/frontend/literature.md:
--------------------------------------------------------------------------------
1 | # IxDF's literature for front-end developers
2 |
3 | > You are reading this [...] for two reasons. First, you are a programmer. Second, you want to be a better programmer. Good. We need better programmers.
4 | >
5 | > -Robert C. Martin (from Clean Code)
6 |
7 | We have, again and again, experienced that it’s not enough to be a good developer — let alone be a developer. We also have
8 | experienced in our team that once a developer has studied the correct content, the code quality and the collective peace of mind
9 | have multiplied. That’s why we have curated a great deal of material for ourselves to become better.
10 |
11 | In IxDF, it is essential for developers to study the content in our library. This list is not here for a developer to ignore.
12 | An IxDF developer should have read the whole library — **at the least**.
13 |
14 | > The frenetic rate of change in our industry means that software developers must continue to learn copious quantities just to keep up.
15 | > Woe to the architects who stop coding—they will rapidly find themselves irrelevant. Woe to the programmers who stop learning new
16 | > languages—they will watch as the industry passes them by. Woe to the developers who fail to learn new disciplines and techniques—their
17 | > peers will excel as they decline.
18 | >
19 | > -Robert C. Martin (from Clean _Coder_)
20 |
21 | ## Index
22 |
23 | You can find all books and videos on the shared folder `IxDF - Shared Reading - Library of Development literature and videos`.
24 | _Warning for devs having small SSDs:_ The videos may take up more than 10gb on your disk. That’s why
25 | you may want to selectively sync those you want to study into your computer when you want to study them.
26 |
27 | 1. Back-end Foundations
28 | 1. Frontend
29 | 1. Foundations
30 | 1. Subscriptions
31 | 1. Awesome lists
32 |
33 | ## Backend
34 |
35 | Every frontend developer should have some backend knowledge to have basic working skills & collaborate with backend developers.
36 |
37 | ### Foundations
38 |
39 | 1. [Laravel Blade](https://laravel.com/docs/master/blade) - PHP template engine. Frontend developers should understand how to
40 | use `@extend`, `@include`, `@component`, `@section`, `@push`, `@foreach` and `@if` directives. They should also understand when they should use `{{ $variable }}` and `{!! $variable !!}` (display escaped/unescaped data).
41 | 1. How to get an instance of the authenticated Member at the view layer and how to determine whether the visitor is a guest or not (see
42 | [🔒 Authenticated Member instance](https://github.com/InteractionDesignFoundation/IxDF-web/docs/library/backend/hints/authenticated-member-instance.md)).
43 | 1. How to
44 | [🔒 create a new route and a new test view for it](https://github.com/InteractionDesignFoundation/IxDF-web/docs/code/backend/hints/create-test-route.md) for testing purposes.
45 | Sometimes it’s a faster way to implement a new feature.
46 |
47 | For more back-end hints, please see [🔒 backend hints dir](https://github.com/InteractionDesignFoundation/IxDF-web/docs/code/backend/hints).
48 |
49 | ## Frontend
50 |
51 | Every frontend developer should
52 |
53 | - have a basic set of programming skills (Foundations),
54 | - be aware of modern techniques, tools, and APIs (Subscriptions and Awesome lists).
55 |
56 | ### Foundations
57 |
58 | 1. Classic programming skills: [Clean Code: JavaScript](clean-code-js.md):
59 | Software engineering principles, from Robert C. Martin's book Clean Code, adapted for JavaScript.
60 | 1. [Eloquent JavaScript](https://eloquentjavascript.net/) (free ebook) or use pdf version from shared library.
61 | 1. [`Martin Fowler - Refactoring - Improving the Design of Existing Code, 2nd edition`](https://martinfowler.com/books/refactoring.html) (book) or use pdf version from shared library.
62 | 1. Design Patterns (book):
63 | [Addy Osmani - Learning JavaScript Design Patterns - 2017](https://addyosmani.com/resources/essentialjsdesignpatterns/book/)
64 | 1. CSS (book): `Verou L. - CSS Secrets - 2015`.
65 | 1. Topic: BEM CSS methodology:
66 | [MindBEMding](https://csswizardry.com/2013/01/mindbemding-getting-your-head-round-bem-syntax/),
67 | [BEM 101](https://css-tricks.com/bem-101/).
68 | 1. Topic:
69 | [KISS, YAGNI & DRY Principles](https://code.tutsplus.com/tutorials/3-key-software-principles-you-must-understand--net-25161)
70 | 1. Optional: Network (book): [Ilya Grigorik - High Performance Browser Networking](https://hpbn.co/).
71 |
72 | ## Subscriptions
73 |
74 | It’s very useful to subscribe to some weekly newsletters or podcasts and be aware of all the events and news in the front-end world.
75 |
76 | 1. JavaScript Weekly newsletter: [javascriptweekly](https://javascriptweekly.com/issues)
77 | 1. Frontend Focus weekly newsletter: [frontendfoc](https://frontendfoc.us/issues)
78 | 1. YouTube channel: [Google Chrome Developers](https://www.youtube.com/channel/UCnUYZLuoy1rq1aVMwx4aTzw).
79 | 1. Dev Channel by ChromiumDev @medium:
80 | [](https://medium.com/feed/dev-channel)
81 | https://medium.com/dev-channel
82 | 1. Optional: CSS weekly newsletter: [css-weekly](https://css-weekly.com)
83 | 1. Optional: Inclusive Components: all about designing inclusive web interfaces:
84 | [](https://inclusive-components.design/rss/)
85 | https://inclusive-components.design/
86 |
87 | ## Awesome lists
88 |
89 | Awesome lists are great starting points for any material you'd like to find: Documentation, articles, talks,
90 | tools, etc. All of them are community curated and always up to date 🌲.
91 |
92 | 1. [Awesome Javascript](https://github.com/sindresorhus/awesome) - a curated list of awesome javascript lists
93 | 1. [Awesome CSS](https://github.com/sotayamashita/awesome-css) - a curated list of awesome frameworks, style guide and other cool nuggets for the amazing CSS.
94 | 1. [Awesome BEM](https://github.com/getbem/awesome-bem)
95 |
96 | 🦄
97 |
--------------------------------------------------------------------------------
/outdated/scrum/README.md:
--------------------------------------------------------------------------------
1 | # Scrum
2 |
3 | According to the official definition, “Scrum is a framework within which people
4 | can address complex adaptive problems, while productively and creatively delivering
5 | products of the highest possible value.”.
6 |
7 | Scrum is a simple, empricial framework which helps us deal with unpredictable, complex problems.
8 |
9 | 
10 |
11 | Scrum implements an empirical process where progress is based on observations of reality, not fictitious plans.
12 |
13 | ## The Scrum Framework
14 |
15 | ### Scrum Values
16 |
17 | 
18 |
19 | ### Scrum Team
20 |
21 | Small team of people, consists of:
22 |
23 | - **[Scrum Master](https://www.scrum.org/resources/what-is-a-scrum-master)**: TBC
24 | - **[Product Owner](https://www.scrum.org/resources/what-is-a-product-owner)**: TBC
25 | - **[Developers](https://www.scrum.org/resources/what-is-a-scrum-developer)**: TBC
26 |
27 | ### [Scrum Pillars](https://www.scrum.org/resources/blog/three-pillars-empiricism-scrum)
28 |
29 | - **Transparency**: This means presenting the facts as is
30 | - **Inspection** (by the Scrum Team): Check the product, processes, people, and practices and you work.
31 | - **Adaptation**: Continuous improvement base on the result of Inspection
32 |
33 | ### Scrum Events
34 |
35 | The main goal of these events is to create regularity and minimize the need for meetings.
36 |
37 | - **[Sprint](https://www.scrum.org/resources/what-is-a-sprint-in-scrum)**:
38 | It is the heart-beat of scrum, which encompasses all the work necessary to achieve the Product Goal.
39 | It's a fixed-length event of one month or less.
40 | - **[Sprint Planning](https://www.scrum.org/resources/what-is-sprint-planning)**: Initiates the sprint by laying out the work to be done.
41 | - Questions:
42 | - Why is this sprint valuable?
43 | - What can be done this sprint?
44 | - How will the chosen work get done?
45 | - Outcome: Sprint Backlog
46 | - See: Definition of Done
47 | - **[Daily Scrum](https://www.scrum.org/resources/what-is-a-daily-scrum)**:
48 | - Purpose:
49 | - Inspect progress toward Sprint Goal
50 | - Synchronize activities
51 | - Plan for the next 24 hours
52 | - Team members often meet immediately after the Daily Scrum for detailed discussions or replan.
53 | - How:
54 | - It's 15 minutes (timebox) to keep everyone focused
55 | - It happens at the same time & location to reduce complexity
56 | - It happens everyday
57 | - It's by developers and for developers
58 | - It's not a status meeting (update on the tasks they've been working on)
59 | - **[Sprint Review](https://www.scrum.org/resources/what-is-a-sprint-review)**:
60 | - Inspect the outcome of the Sprint & determine future adaptation
61 | - Progress toward Product Goal is discussed with stakeholders
62 | - Maximum of 4-hour timeboxed event for a 4-week Sprint
63 | - See: Backlog Refinement
64 | - **[Sprint Retrospective](https://www.scrum.org/resources/what-is-a-sprint-retrospective)**:
65 | - Inspect individuals, interactions, processes, tools, and their Definition of Done.
66 | - Identify the most helpful changes to improve effectiveness.
67 | - It's timeboxed to a maximum of 3 hours for a 4-week Sprint.
68 |
69 | ### Scrum Artifacts
70 |
71 | Scrum Artifacts enable inspection & adaptation by providing transparency on the work and the value.
72 |
73 | - **[Product Backlog](https://www.scrum.org/resources/what-is-a-product-backlog)**:
74 | - Definition: An emergent, ordered-list of what's needed to improve the product.
75 | - Commitment: Product Goal, which is a future state of the product that helps
76 | Scrum Team to plan their future Sprints. It's either fulfilled or abandoned.
77 | - **[Sprint Backlog](https://www.scrum.org/resources/what-is-a-sprint-backlog)**:
78 | - Definition:
79 | - Sprint Goal (Why)
80 | - Set of Product Backlog Items (What)
81 | - Actionable plan for delivering the Increment (How)
82 | - Commitment: Sprint Goal, which is a single commitment for the sprint. It has
83 | flexibility in terms of the exact work needed to achieve it.
84 | - **[Increment](https://www.scrum.org/resources/what-is-an-increment)**:
85 | - Definition:
86 | - Concrete stepping stone toward the Product Goal.
87 | - Each increment is added to the previous
88 | - All increments should work with each other
89 | - Commitment: Definition of Done, which is a formal description of the minimum
90 | quality required for an increment to be accepted.
91 |
92 | Scrum works not because it has three roles, five events,
93 | and three artifacts, but because it adheres to the underlying
94 | Agile principles of iterative, value-based incremental delivery by frequently gathering
95 | customer feedback and embracing change.
96 |
97 | ### External, introductory resources
98 |
99 | - **[What is Scrum?](https://www.scrum.org/resources/what-is-scrum)**: A short overview of what Scrum is
100 | - **[Scrum Glossary](https://www.scrum.org/resources/scrum-glossary)**: A short Scrum glossary with the most essential terms
101 | - **[Scrum Values](https://kissflow.com/project/agile/how-to-apply-5-scrum-values/)**: Practical examples of applying Scrum Values
102 |
103 | ## More external resources
104 |
105 | - [Sprint planning](https://www.mountaingoatsoftware.com/agile/scrum/meetings/sprint-planning-meeting)
106 | - [Daily scrum](https://www.mountaingoatsoftware.com/agile/scrum/meetings/daily-scrum)
107 | - [Demo/Review meeting](https://www.mountaingoatsoftware.com/agile/scrum/meetings/sprint-review-meeting)
108 | - [Sprint retrospective](https://www.mountaingoatsoftware.com/agile/scrum/meetings/sprint-retrospective)
109 |
110 | ## Scrum in IxDF
111 |
112 | TBC
113 |
114 | 🦄
115 |
--------------------------------------------------------------------------------
/guides/onboarding/onboarding--buddyGuide.md:
--------------------------------------------------------------------------------
1 | # Onboarding Buddy
2 |
3 | Every new team-member will be paired with an onboarding buddy to make their onboarding
4 | smooth. The onboarding buddy should work in _almost_ the same timezone as the new team member.
5 |
6 | ## How to be a great Onboarding Buddy
7 |
8 | We have an "Onboarding Buddy playbook" in our shared folder that you should read
9 | and follow in order to create the ultimate onboarding experience for a new team member
10 | (in addition to all the resources on “Onboarding & Company Culture Course” you
11 | should be enrolled to).
12 |
13 | Your main work as an Onboarding Buddy is to help the new team member feel welcome,
14 | not to lose track, and finally get their feedback and transform it into actions like:
15 |
16 | - Update documentation
17 | - Create issues (e.g. `Make dev env works with latest version of XYZ`)
18 | - Make a proposal to optimize the onboarding process
19 | - etc.
20 |
21 | ## Expectations and duties
22 |
23 | It’s not the job of an onboarding buddy to ~teach~, although you might end up doing
24 | a little of that. Your role is to **guide** and inspire with your enthusiasm.
25 |
26 | So while there’s an element of teaching, the skills an onboarding buddy
27 | needs are different to those of a teacher. You need to be an attentive listener,
28 | and you need to have enough practical experience to be able to give your buddy
29 | the right advice at the right time.
30 |
31 | **Set expectations**: Communicate your expectations in a simple and direct manner.
32 | Clarify expected roles, processes and outcomes.
33 | Ensure your buddy understands your expectations and feels motivated to fill them.
34 |
35 | ## Plan
36 |
37 | ### Goals
38 |
39 | Here's a list of things to consider when we try to onboard a new member:
40 |
41 | 1. Make them feel welcome
42 | 1. Make them feel proud of what they do
43 | 1. Connect them to the bigger picture (the WHY)
44 | 1. Let them know why and how much they matter
45 | 1. Try to offload as much information as we can into our shared folders and documents
46 | 1. Make it easy for them to access all necessary information
47 | 1. Simplify the feedback loop (bidirectional)
48 |
49 | ### First day
50 |
51 | 1. Ensure that your buddy has read all onboarding documents.
52 | 1. Ensure that your buddy has all accounts/permissions for our internal and 3rd-party
53 | services (see [Tools and Services checklist](#checklist-for-tools-and-services)).
54 | 1. Ensure that your buddy has [🔒 properly installed developer environment](https://github.com/InteractionDesignFoundation/IxDF-web/blob/main/docs/environment/first-run/README.md).
55 | 1. Arrange end-of-day meetings with your buddy with a specified agenda to get maximum feedback.
56 | The meeting should happen at the end of each day during the first week.
57 | Why: It will help your buddy understand if they are doing what's expected of the
58 | at the right pace and are focused on the correct tasks, as well as receive
59 | clear instructions, advice and constructive criticism to help them improve.
60 | 1. Start changing code: Prepare 3-10 tasks for smooth entry into the project. Examples:
61 | 1. Write tests for feature X (the goal is to introduce feature X, introduce our tools and workflows (GitHub, git, CI))
62 | 1. Pickup and fix any bug from our automated bug-report systems (Slack, New Relic, Bugsnag, etc.) (goal: introduce tools, fix a bug)
63 | 1. Review a Pull Request (goal: introduce our Pull Request flow and a new piece of code).
64 |
65 | ### First week
66 |
67 | 1. Ensure that your buddy has a plan to read developer and general literature
68 | as well as materials from our shared folders (50/50 mix of general/developer literature).
69 | 1. Ask for a summary feedback for the first week.
70 |
71 | ### First month
72 |
73 | 1. Ensure that you got maximum feedback from your buddy and transformed it into actions.
74 |
75 | ### In a month: finish mentoring
76 |
77 | **Evaluate developer onboarding process**: Now you need to evaluate the onboarding
78 | process to make sure that everything is up to the standard.
79 |
80 | When evaluating the process, simply refer to [our goals](#goals) and answer the
81 | following questions:
82 |
83 | 1. Do we have an effective mentoring program?
84 | 1. What/how can we improve? This includes documents, processes, tools, etc.
85 |
86 | ## Checklist for Tools and Services
87 |
88 | This is a list of tools and services that a new member should have access to.
89 | Dev specific (usually handled by a dev team lead):
90 |
91 | - [GitHub](https://github.com): Source code storage, issue tracker and CI/CD tool. Ensure that the new developer is attached to the `devs` team.
92 | - [Laravel Forge](https://forge.laravel.com/circles/4114/edit): Server Provision service for our servers & sites. Mentee should be added to "Development Team" circle. Ensure 2FA is enabled.
93 | - [PHPStorm license](https://account.jetbrains.com/assets/subscriptions): send an invitation to a corporate gmail account.
94 | - [Downnotifier](https://downnotifier.com/): Set cell phone numbers to subscribe to emergency notifications.
95 | - Optional: [Google Analytics](https://analytics.google.com): Analytics service that tracks and reports website traffic.
96 | - Optional: [Google search console](https://www.google.com/webmasters/tools): Monitor Google Search results data.
97 | - [GTmetrix](https://gtmetrix.com/): Analyze web page's speed performance [👥 shared account].
98 | - [New Relic](https://newrelic.com/): Log errors and monitor application performance [👥 shared account].
99 |
100 | Company-wide services (usually handled by a Hiring Process Manager):
101 |
102 | - [Gmail](https://gmail.com): Corporate email box.
103 | - [Slack](https://interaction-design.slack.com): Our main communication tool. Ensure that the new developer is attached to `Developers` slack team/user-group.
104 | - [Dropbox.com](https://sync.com): Cloud service to share materials, literature, media, etc. Ensure that the new developer has access to all directories that they need: designs, literature (both: general and developers), etc.
105 | - [LastPass](https://www.lastpass.com/): Credentials management tool: store and share credentials.
106 | - [Figma](https://figma.com/): Share designs and assets between designers and developers.
107 |
108 | 🦄
109 |
--------------------------------------------------------------------------------
/images/agile-sprints.svg:
--------------------------------------------------------------------------------
1 |
48 |
--------------------------------------------------------------------------------
/guides/OKR/03-create-your-okrs.md:
--------------------------------------------------------------------------------
1 | # Create Your OKRs
2 |
3 | Once you know [about OKRs](./00-why-okrs), about the IxDF's [OKR cadence](./01-okr-cadence) and our [cascading OKR's](./02-cascading-okrs), you are ready to begin creating your own OKR's.
4 |
5 | ## Familiarize yourself with the OKR Planning Spreadsheet
6 |
7 | 1. Please familiarize yourself with the spreadsheet called “IxDF OKR Planning.xlsx”, which you will find in the folder [IxDF / IxDF - PeopleAndCulture - Job Roles and Organizational Structure](https://www.dropbox.com/home/IxDF%20-%20PeopleAndCulture%20-%20Job%20Roles%20and%20Organizational%20Structure) on our DropBox instance—Available only to IxDF team members.
8 | 2. Study some examples of Objectives, Key Results, and how we measure them really closely.
9 | 3. Read all the “help bubbles” that explain the contents of the cells.
10 | 4. Don’t worry if you don’t fully understand what’s going on when you read the spreadsheet. We’ll explain on the next steps.
11 |
12 | After you’re done, proceed to the next step. Now it’s your turn to define Objectives, Key Results, and some KPIs to measure the progress of your Key Results before your Quarterly OKR Planning Meeting.
13 |
14 | ## Fill Out the Spreadsheet Before the Quarterly OKR Meeting
15 |
16 | 
17 |
18 | What you do next:
19 |
20 | 1. Fill out the relevant part of the next quarter’s tab in the IxDF OKR Spreadsheet
21 | - If you are a Team Lead, then fill out the Team-wide OKRs, and NOT the Personal OKRs for each Team Member. After that, you hold a meeting with the Executive Level before you hold a meeting with your Team.
22 | - If you are a Team Member, then fill out your Personal OKRs, after which you hold a 1:1 meeting with your Team Lead to refine/improve your Personal OKRs and make sure they are aligned with the Team’s.
23 | 2. Now you’re prepared to hold the Quarterly OKR Meeting, which is the next step in the process.
24 | 3. If you are a Team Lead you FIRST hold a Quarterly OKR Meeting with the Executive Level to get their feedback and approval. THEN, you hold a Quarterly OKR Meeting with your Team.
25 |
26 | ## Define Your Objectives
27 |
28 | 
29 |
30 | Now, write down your Personal – or your Team’s Objectives. If you’re a Team Lead, you write down your Team’s Objectives. If you’re a Team Member, you write down your Personal Objectives .
31 |
32 | 1. What are the most important impact(s) that I – or my Team – need to make in the coming quarter?
33 | - If you are defining Personal Objectives, then based it on my Team’s Objectives for this quarter
34 | - If you are a Team Lead defining your Team’s Objectives, then base it on the IxDF-wide Objectives)
35 |
36 | Spend some time brainstorming ideas on sticky notes – while doing deep concentration. Group similar ideas together. From there, distill your ideas down into 3 to 5 aspirational Objectives.
37 |
38 | Objectives should be high-level, qualitative statements that are aspirational – not tasks or granular outcomes.
39 |
40 | Please refer to the examples you just read in the “OKR Planning Spreadsheet”
41 |
42 | ## Define Your Key Results
43 |
44 | 
45 |
46 | Define your Key Results for each Objective
47 |
48 | - How do you measure progress toward a qualitative goal that is inherently un-measurable? You identify measurable outcomes that indicate you’ve achieved your Objective!
49 | - Many people struggle to set Key Results for a qualitative goal. Often they think that qualitative Objectives are unmeasurable. However, by focusing on outcomes it becomes easier.
50 | - Now, for each Objective that you just defined, think about the results you would see (and can measure) if you reached that objective. Again, these are not tasks or to-dos. These are outcomes/results.
51 | - Wrong: “Ship feature X by the end of the quarter.”Right: “Shipping feature X increases new user sign-ups by 10% this quarter.”
52 | - Wrong: “Improve customer experience by the end of the quarter.”Right: “Lower customer service calls by X by end of quarter.”
53 | - If you are the Team Lead:
54 | - Assign each Key Result an Owner on the Team. If a Key Result requires collaboration with another Team, great! The Owner should follow up with them afterwards and make sure they’re on board.
55 |
56 | Please refer to the examples you just read in the “OKR Planning Spreadsheet”.
57 |
58 | ## Define Your KPIs
59 |
60 | 
61 |
62 | A KPI (Key Performance Indicator) is a metric used to measure something, i.e. it’s an “indicator of performance”. Here’s an example:
63 |
64 | - **Objective 1**: Become the most popular bootcamp in UX
65 | - **Key Result 1 for Objective 1**: Double the amount of sign-ups from 50 to 100 students per cohort.
66 | - **KPI for Key Result 1**: Number of Students per cohort
67 |
68 | As mentioned, the KPI for the Key Result 1 would be “Number of Students per cohort” and you would be able to publish a direct link to the NOVA Bootcamp Control Panel where you can read the always-updated value of that KPI, which may currently be 73 students per cohort.
69 |
70 | KPIs are superb (and fun!) ways to measure exact progress. Whenever possible, use KPIs to measure your progress.
71 |
72 | 
73 |
74 | ## Ramp Up Your Ambition
75 |
76 | 
77 |
78 | Are you done defining your Objectives and Key Results? Great! Then it’s time to give them one more iteration!
79 |
80 | Please do the following:
81 |
82 | 1. Review the Objectives and Key Results you’ve defined and ask whether they’re ambitious enough. If you feel totally confident, you can hit a Key Result, increase the target by approximately 30% and then create a plan mapping out how you will achieve it. If you’re not at all sure you’ll hit a Key Result target, it’s probably set just right.
83 | 2. Make sure the Key Results are articulated well and detailed. You want to be able to score them later on a percentage scale.
84 | 3. Go to the next step about “S.M.A.R.T” and use that as a checklist (see the next step).
85 | 4. Lastly, consider whether you have too many or too few Objectives and Key Results.
86 |
87 | ## Ensure Your OKRs are S.M.A.R.T
88 |
89 | 
90 |
91 | ## Hold a Quarterly OKR Meeting
92 |
93 | 
94 |
95 | The Quarterly OKR Planning Meeting
96 |
97 | - The Team Lead makes a new entry for a new quarter for their team by creating a new section in the first tab of the spreadsheet “IxDF OKR Planning.xlsx”
98 | - The Team Lead closely studies the IxDF-wide Objectives
99 | - The Team Lead takes a call with the IxDF Executive Level and asks questions. The better aligned we are, the smoother everything goes.
100 | - The Team Lead fills out all OKRs for their team as best as possible.
101 | - This is a concentration-demanding and lengthy process. It requires strategic overview, long-term thinking, and the ability to constantly switch mindset from “strategic, high-level, long-term thinking” to “concrete execution-level work”.
102 | - Expect this to take up to a full day of high-concentration work – perhaps spread out over several days if your brain starts to burn.
103 | - The Team Lead meets with the Executive Level to verify and refine the Team’s OKRs.
104 | - The Team Lead then meets with their Team where the Team Lead presents the plan for the next quarter.
105 | - Each Team Member then develops Personal OKRs based on the Team’s OKRs.
106 | - Each Team Member meets 1:1 with the Team Lead to verify and refined their Personal OKRs.
107 |
108 | With your OKR's created, it is time to execute on them for the next six weeks, but to do so effectively,
109 | you will need to [stay aligned as a team](./04-stay-aligned-as-a-team).
110 |
--------------------------------------------------------------------------------
/images/continuous-delivery.svg:
--------------------------------------------------------------------------------
1 |
26 |
--------------------------------------------------------------------------------
/library/frontend/conventions--jsdoc.md:
--------------------------------------------------------------------------------
1 | # IxDF's JSDoc Conventions
2 |
3 | For JavaScript code documentation, we use [JSDoc blocks](http://usejsdoc.org/).
4 | There are a few type declarations standards in the JS ecosystem, namely:
5 |
6 | - [JSDoc](https://jsdoc.app/)
7 | - [Google Closure Compiler](https://github.com/google/closure-compiler/wiki/Types-in-the-Closure-Type-System)
8 | - [TypeScript](https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html)
9 |
10 | We use the most compatible and least confusing options from all of them.
11 | Most likely, your IDE and tools we use also support all of them.
12 | This document is created to avoid confusion and increase consistency.
13 |
14 | ---
15 |
16 | [[toc]]
17 |
18 | ## JSDoc vs. PHPDoc
19 |
20 | Comparing with [PHPDoc](./../backend/conventions--php#docblocks), there are some differences:
21 |
22 | 1. JSDoc uses`@returns` instead of `@return`;
23 | 2. Curly brackets are used as wrappers for variable types, e.g., `{Object}`, `{Array}`.
24 | 3. `{number}` is used instead of `integer` and `float` in PHPDoc.
25 |
26 | A good example of using JSDoc:
27 |
28 | ```js
29 | /**
30 | * Sends logging information to server.
31 | *
32 | * @param {string} errorMessage Message to send.
33 | * @param {string} [fileName] Name of the file where the logging event was discovered
34 | * @param {Object} [postedData = {}] POST body data, provides some context of the logging event (optional with default value).
35 | * @returns {boolean} Whether it was sent.
36 | */
37 | function logError(errorMessage, fileName, postedData = {}) {
38 | // some code
39 | }
40 | ```
41 |
42 | ## Tags
43 |
44 | The most used JSDoc block tags:
45 |
46 | - [@param](http://usejsdoc.org/tags-param.html) for describing function parameters.
47 | - [@returns](http://usejsdoc.org/tags-returns.html) for describing the return type of functions.
48 | - [@type](http://usejsdoc.org/tags-type.html) to specify the type of variable.
49 | - [@typedef](http://usejsdoc.org/tags-typedef.html) to define a data structure.
50 |
51 | ## Types
52 |
53 | ### Scalars
54 |
55 | Use lowercase notation:
56 |
57 | ```js
58 | /** @type {string} */
59 | /** @type {number} */
60 | /** @type {function} */
61 | ```
62 |
63 | ### Nullable types
64 |
65 | ```js
66 | // Nullable
67 | /** @param {?string} userName */
68 | /** @param {?HTMLElement} element */
69 |
70 | // Also nullable (using Type Union syntax)
71 | /** @param {string|null} userName */
72 | /** @param {HTMLElement|null} element */
73 |
74 | // Not nullable (we don't use this syntax: all types are not nullable by default (except null) according to our conventions)
75 | /** @param {!string} userName */
76 | /** @param {!HTMLElement} element */
77 | ```
78 |
79 | ::: info
80 | Whether a type is nullable or not nullable by default? - **Not nullable**!
81 |
82 | There is confusion around this, both TypeScript and Closure compiler treat scalars as not nullables by default,
83 | but Closure treats Instance Types as nullable (TypeScript doesn’t).
84 | We have chosen the TypeScript way here.
85 | :::
86 |
87 | ### Optional parameters
88 |
89 | ```js
90 | // The most conventional and widely recognized. The square brackets denote that the parameter is optional.
91 | /** @param {string} [userName] */
92 |
93 | // Optional with default value
94 | /** @param {string} [userName='Unknown'] */
95 |
96 | // Also optional. Used in Google Closure Compiler (understood by most JSDoc parsers but is less commonly used)
97 | /** @param {string=} userName */
98 | ```
99 |
100 | ### Type Union
101 |
102 | ```js
103 | /** @type {(number|boolean)} */
104 | /** @type {function(string|number):(string|number)} */
105 | ```
106 |
107 | ### Function type
108 |
109 | ```js
110 | /** @type {function()} */
111 | /** @type {function(): number} */
112 | /** @type {function(string, number): number} */
113 | /** @type {function(string, ...number): number} */
114 | /** @type {function(?string=, number=): number} */
115 | ```
116 |
117 | ### Generics
118 |
119 | ```js
120 | /**
121 | * Standard JS objects:
122 | * @type {Promise}
123 | * @type {Array}
124 | * @type {Array}
125 | * @type {Set}
126 | * @type {WeakMap}
127 | */
128 |
129 | /**
130 | * Custom generic:
131 | * @template T
132 | * @param {T} thing
133 | * @returns {Array}
134 | */
135 | export function wrapByArray(thing) {
136 | return [thing];
137 | }
138 | ```
139 |
140 | Note, we use TypeScript/Closure notation for generics: `{Array}`.
141 | We do not use the traditional JSDoc syntax: `{Array.}` (the dot is the only difference).
142 |
143 | [More about Generics in Google Closure compiler](https://github.com/google/closure-compiler/wiki/Generic-Types).
144 |
145 | ### Custom types
146 |
147 | #### @typedef tag
148 |
149 | You can specify your custom structure using **typedef** tag:
150 |
151 | ```js
152 | /**
153 | * @typedef {Object} User
154 | * @property {string} name
155 | * @property {string} email
156 | * @property {string|null} phone
157 | */
158 |
159 | /**
160 | * Or shorthand version:
161 | * @typedef {{name: string, email: string, phone: string|null}} User
162 | */
163 |
164 | /**
165 | * @param {User} user
166 | */
167 | function isAdmin(User) {
168 | //
169 | }
170 | ```
171 |
172 | This is suitable for cases when you are going to use this type within the same file only.
173 |
174 | #### Type Definition Files
175 |
176 | For types used in different files, the preferable option is to use TypeScript syntax
177 | and extract the type definition into a separate `.d.ts` file.
178 | Then you can import this type using JSDoc:
179 |
180 | ```js
181 | /**
182 | * @typedef {import('./user.d.ts').User} User
183 | */
184 | ```
185 |
186 | ### Destructured parameters
187 |
188 | **Flat Structures**: document each property on its own line:
189 |
190 | ```js
191 | /**
192 | * @param {Object} user
193 | * @param {string} user.name - The name property.
194 | * @param {?string} user.phone - The phone property, which is nullable.
195 | */
196 | function logUser({name, phone}) {
197 | //
198 | }
199 | ```
200 |
201 | **Nested Structures**:
202 |
203 | ```js
204 | /**
205 | * @param {Object} config - The configuration object.
206 | * @param {string} config.user.name - The user's name.
207 | * @param {?string} config.user.phone - The user's phone number, which is nullable.
208 | * @param {Object} config.settings - The settings object.
209 | * @param {boolean} config.settings.isActive - Indicates if the settings are active.
210 | */
211 | function initialize({
212 | config: {
213 | user: {name, phone},
214 | settings: {isActive},
215 | },
216 | }) {
217 | // function body
218 | }
219 | ```
220 |
221 | **Clarity and Conciseness**: Avoid overly complex structures in function parameters.
222 | If a function accepts numerous or deeply nested parameters,
223 | consider refactoring the function or using a type definition to simplify the documentation and enhance code readability.
224 |
225 | ### Advanced TypeScript types and expressions
226 |
227 | ```js
228 | /**
229 | * Takes any union type and excludes `null`
230 | * @template T
231 | * @param {T} thing
232 | * @returns {Exclude}
233 | */
234 | export function assertNonNull(thing) {
235 | if (thing === null) {
236 | throw new Error('Unexpected null.');
237 | }
238 | return thing;
239 | }
240 |
241 | // or the same
242 |
243 | /**
244 | * Takes any union type and excludes `null`
245 | * @template T
246 | * @param {T} thing
247 | * @returns {NonNullable}
248 | */
249 | export function assertNonNull(thing) {
250 | if (thing === null) {
251 | throw new Error('Unexpected null.');
252 | }
253 | return thing;
254 | }
255 | ```
256 |
257 | ## References
258 |
259 | - [JSDoc Cheatsheet](https://devhints.io/jsdoc).
260 | - [JSDoc Cheatsheet for TypeScript users](https://docs.joshuatz.com/cheatsheets/js/jsdoc/).
261 | - [Types in the Closure Type System](https://github.com/google/closure-compiler/wiki/Types-in-the-Closure-Type-System).
262 | - [Overview](https://www.jetbrains.com/webstorm/help/creating-jsdoc-comments.html) for using JSDoc PHPStorm and
263 | WebStorm.
264 |
--------------------------------------------------------------------------------
/public/images/hydrogenlogo.svg:
--------------------------------------------------------------------------------
1 |
50 |
--------------------------------------------------------------------------------
/library/frontend/conventions--vuejs.md:
--------------------------------------------------------------------------------
1 | # IxDF's Vue.js conventions
2 |
3 | These conventions are based on the official [Vue.js style guide](https://vuejs.org/style-guide/). Where a choice is given
4 | between various options, this document will explicitly state which one to pick within the IxDF codebases.
5 |
6 | [[toc]]
7 |
8 | ## Use multi-word component names
9 |
10 | User component names should always be multi-word, except for root App components.
11 | This prevents conflicts with existing and future HTML elements, since all HTML elements are a single word.
12 |
13 | **Bad**
14 |
15 | ```html
16 |
17 | ```
18 |
19 | **Good**
20 |
21 | ```html
22 |
23 | ```
24 |
25 | ## Always add detailed prop definitions
26 |
27 | Prop definitions should always be as detailed as possible.
28 |
29 | **Bad**
30 |
31 | ```js
32 | const props = defineProps(['status']);
33 | ```
34 |
35 | **Good**
36 |
37 | ```js
38 | // With TypeScript (recommended)
39 | const props = defineProps<{
40 | status: string
41 | }>()
42 |
43 | // Without TypeScript
44 | const props = defineProps({
45 | status: {
46 | type: String,
47 | required: true,
48 | }
49 | })
50 | ```
51 |
52 | ## Add a key when using `v-for`
53 |
54 | A key with v-for is always required on components, in order to maintain internal component state down the subtree.
55 |
56 | **Bad**
57 |
58 | ```html
59 |
370 |
371 | ```
372 |
373 | ## Single-file component top-level element order
374 |
375 | Single-File Components should always order `
385 |
388 | ```
389 |
390 | **Good**
391 |
392 | ```html
393 |
394 |
397 | ...
398 |
401 | ```
402 |
--------------------------------------------------------------------------------
/outdated/design-products/delivery-process.md:
--------------------------------------------------------------------------------
1 | # Delivery Process
2 |
3 | This is the process we use to turn product designs into actual products.
4 |
5 | ## Agile Teams
6 |
7 | 
8 |
9 | ### Agile Team Members
10 |
11 | - Member Experience
12 | - Growth
13 | - Development
14 | - Editorial
15 | - Video
16 | - Product Owner
17 | - Design
18 |
19 | ## Agile Organization
20 |
21 | 
22 |
23 | Leverage **epics**, **milestones**, **issues** and **labels** to manage execution of tasks.
24 |
25 | ### Epics
26 |
27 | **Epics** are high level product requirements and/or features requests that require multiple issues to achieve. Epics
28 | may extend into multiple milestones “sprints” or continue indefinitely for iterative improvements (e.g. accessibility
29 | improvements).
30 |
31 | ### Milestones (Sprints)
32 |
33 | 
34 |
35 | **Milestones** are bi-weekly “fort-nightly” sprints that are two weeks in duration. Milestone consists of multiple
36 | issues that will be addressed in a given sprint.
37 |
38 | - **Now**: Design related tasks for this sprint.
39 | - **Next**: Design related tasks for the next sprint.
40 | - **Later**: Design related tasks for a later sprint.
41 |
42 | **Please Note**: Alternative naming conventions for milestones include a **numeric** (#01, #02, #03) or **date** (
43 | DD-MM-YYYY) approaches.
44 |
45 | ### Scrum Board
46 |
47 | 
48 |
49 | **Scrum** is an iterative way of working that focuses on breaking down big projects into small, manageable sprints, with
50 | an emphasis on communication and teamwork — and the scrum board embodies this. This board sits at the center of
51 | everything the team does. It shows how far along they are in the sprint, as well as the overall project.
52 |
53 | - **Backlog**: A full list of issues (edits, features, bugs).
54 | - **To Do**: Issues that will be tackled during the milestone “sprint.”
55 | - **In-Progress**: Issues currently being worked on.
56 | - **In-Review**: Issues ready for review or blocked.
57 | - **Done**: Issues that have been completed.
58 |
59 | ### Issues
60 |
61 | 
62 |
63 | **Issues** are tasks, design requests, new features or bugs that will be addressed in each milestone.
64 |
65 | #### GitHub Issue Types
66 |
67 | - Design Request: Design a landing page.
68 | - Bug Report: Fix broken cta button.
69 | - Feature or Idea: Add note taking feature.
70 | - Design Edit: Make the logo bigger.
71 |
72 | #### How to Create a GitHub Issue?
73 |
74 | - Issue added to GitHub by a team member. The team member will then assign the appropriate colleague(s) and the issue is
75 | automatically added to the backlog.
76 | - Label added to issue (e.g. `urgency:3`).
77 | - Issue(s) will be assigned by the appropriate Epic by the team member assigned.
78 | - Issue(s) will then be placed in a Milestone based on priority during sprint planning.
79 |
80 | ### Labels
81 |
82 | **Labels** are assigned tags that help organize individual issues (e.g. design request, bootcamp, bug) and indicate the
83 | level of priority (e.g. low, medium, high).
84 |
85 | ## Agile Software
86 |
87 | 
88 |
89 | ### GitHub
90 |
91 | **GitHub** as a way to manage execution of tasks (how, when, what).
92 |
93 | - Leverage GitHub to track progress of tasks.
94 |
95 | ### AirTable
96 |
97 | **AirTable** to display roadmap, discovery, and gather user research and feedback from the MEx team.
98 |
99 | - Leverage Gantt View to display high-level roadmap.
100 | - Leverage individual records to gather user feedback and research.
101 |
102 | ### Docs
103 |
104 | **Docs** for notes and documentation (e.g. this document).
105 |
106 | ### Slack
107 |
108 | **Slack** for communication and updates. MIRO for collaboration and ideation sessions.
109 |
110 | ## Delivery Criteria
111 |
112 | 
113 |
114 | ### How to Determine Priority?
115 |
116 | Use **Delivery Criteria** to determine priority of issues. The criteria include the **C.H.I.M.E. Metric** of
117 | Maintainability, Impact, Confidence and Ease.
118 |
119 | - **Confidence**: How confident are you in these estimates?
120 | - **Hypothesis**: What do you think is the ROI on this feature?
121 | - **Impact**: How much will this feature impact our members?
122 | - **Maintainability**: How easy is this to maintain over the long-term?
123 | - **Ease/Effort**: What is the development time investment for this feature?
124 |
125 | ## Design Decisions
126 |
127 | How to Make Design Decisions? In order to create the best possible user experience, you should leverage best practices
128 | to help make decisions. We should ask ourselves; **does it violate any of
129 | our [Design Principles](/outdated/design-products/design-principles.md)**?
130 |
131 | **If not, then proceed** :)
132 |
133 | ## Discovery and Delivery Sprints
134 |
135 | 
136 |
137 | ### Discovery: AirTable
138 |
139 | - Christian comes up with an idea for electric shock-enabled education and adds it to AirTable as a record that is labeled as an **idea**.
140 | - Christian Mentions the appropriate team members in an AirTable discussion.
141 | - Before the next Quarterly/Team OKR.
142 | - Team member discussion ensues.
143 | - Voting may happen, possibly against **delivery criteria**.
144 | - **Delivery criteria** will determine if the idea is placed in the roadmap. (e.g., does it align with an **Annual/IxDF OKR**? Does it violate our **IxDF design principles**? **M.I.C.E. Score**? **Practical Idealism**?)
145 | - In the next **Quarterly/Team OKR** meeting, If the idea meets the **delivery criteria**, it is added to the roadmap.
146 | - Assigned to the appropriate team(s).
147 | - Example: Design and Development team collaborate on new electric shock-enabled feature.
148 | - Example: Video, Editorial and Growth teams collaborate on a course promo video.
149 | - KR’s are defined for it, which could include:
150 | - Attributes (e.g. feature should have x, y, z)
151 | - Adoption (e.g., x number of users by 21Q4)
152 | - Dates (e.g., launch feature by 21Q3)
153 |
154 | ### Delivery: GitHub
155 |
156 | - Create related GitHub epic with associated issues.
157 | - Team members assigned, requirements explained, added to milestone (See Sprint Planning Process).
158 | - Insert design and/or dev issue template link here.
159 |
160 | ## Design Meetings
161 |
162 | If helpful, you may use these meetings as a guide for your team.
163 |
164 | - **Daily Standup**:
165 | - Daily / Monday–Friday / Via Slack
166 | - Share what you completed today, what you plan on completing tomorrow, and are there any blockers.
167 | - **Sprint Planning**:
168 | - Bi-Weekly (Fortnightly) / Monday / Via Google Hangouts, Slack or Zoom
169 | - Review backlog, determine priority of issues, provide estimates, check goals (i.e. dependencies, clarifications), confirm consensus.
170 | - **Sprint Retrospective**:
171 | - Bi-Weekly (Fortnightly) / Monday / Via Google Hangouts, Slack or Zoom
172 | - Share what went well, what could be improved, define actionable tasks to improve the next sprint.
173 | - **Backlog Refinement**:
174 | - Bi-Weekly (Fortnightly) / Monday / Independently Prior to Sprint Planning
175 | - Clean up backlog issues, determine priority, make sure issues are in alignment with goals, organize in preparation for planning.
176 |
177 | ## Design Sprint Planning
178 |
179 | If helpful, you may use this sprint planning agenda as a guide for your team.
180 |
181 | 1. Hellos :)
182 | 2. **Team Updates** (i.e. Events, Availability, New Systems, Problems).
183 | 3. Collectively **Review Backlog**.
184 | 1. Review backlog, determine priority of issues, provide estimates, check goals (i.e. dependencies, clarifications), confirm consensus.
185 | 4. **Determine Priority** of Issues.
186 | 1. Determine the importance of each issue, make sure each issue is understood, be sure it aligns with our organization goals, and discuss if all issues are represented (i.e. avoid unanticipated tasks).
187 | 5. **Add the Right Mix** of Issues to the To Do Column.
188 | 1. Reject any unsuitable issues (i.e. redundant, badly defined, too big, team can’t control, etc), move the most likely candidates to the todo column, rank them in priority order.
189 | 6. **Check Estimates** & **Assign Work**.
190 | 1. Review workload, add contingency & reserved time for unanticipated issues, determine if we're using everyone’s strengths, are we too ambitious, is anyone overloaded?
191 | 7. **Check Goals**.
192 | 1. Any assumptions? Dependencies? Clarifications needed?
193 | 2. Ask questions, flag any potential problems.
194 | 3. Articulate the sprint goals for us to commit to.
195 | 8. **Determine** 100% Consensus.
196 | 1. If not, repeat step 3 :)
197 |
198 | ## Helpful Agile Terms
199 |
200 | 
201 |
202 | Below is a list of helpful agile terms.
203 |
204 | - **Daily Standup**: Share what you completed today, what you plan on completing tomorrow, and are there any blockers.
205 | - **Sprint Planning**: Review backlog, determine priority of issues, provide estimates, check goals (i.e. dependencies, clarifications), confirm consensus.
206 | - **Sprint Retrospective**: Share what went well, what could be improved, define actionable tasks to improve the next sprint.
207 | - **Backlog Refinement**: Clean up backlog issues, determine priority, make sure issues are in alignment with goals, organize in preparation for planning.
208 | - **Blockers**: A blocker is anything that is keeping somebody from performing a specific task.
209 | - **OKR**: The acronym OKR stands for Objectives and Key Results. The OKR is a popular strategy for goal setting within organizations. It is a collaborative goal-setting tool which we can use to realize our vision and mission in the best possible way.
210 | - **Objective**: An Objective is a description of a goal to be achieved in the future. An Objective sets a clear direction and provides motivation. An Objective can be thought of as a destination on a map..
211 | - **Key Result**: A Key Result is a metric with a starting value and a target value that measures progress towards an Objective. A Key Result is like a signpost with a distance that shows how close you are to your Objective.
212 | - **Task**: A task is a description of the work you’ll do to influence a Key Result. If an Objective is your destination and a Key Result shows the distance to go, a task describes what you’ll do to get there, (take a car, row a boat, etc.).
213 | - **Annual/IxDF OKRs**: Annual meetings between key stakeholders to discuss organizational OKRs (e.g., culture, hiring, product, editorial courses).
214 | - **Quarterly/Team OKRs**: Quarterly meetings between teams leads to determine product priorities (e.g., bootcamp grading feature, IxDF shop).
215 | - **M.I.C.E. Score**: Stands for maintainability, impact, confidence and ease.
216 | - **Maintainability**: How easy is this to maintain over the long-term?
217 | - **Impact**: How much will this feature impact those users?
218 | - **Confidence**: How confident are you in these estimates?
219 | - **Ease**: What is the time investment for this feature?
220 | - **S.M.A.R.T.**: Stands for specific, measurable, achievable, realistic and timely.
221 | - **Discovery**: Product discovery focuses on generating ideas for the backlog.
222 | - **Delivery**: Product delivery focuses on implementing the discovery ideas.
223 | - **Impractical Idealism**: Attempting to achieve an idealistic goal—like bringing design education into all corners of the world—using only idealistic success criteria (e.g., maximum number educated, top quality, low cost).
224 | - **Practical Idealism**: Attempting to achieve an idealistic goal—like bringing design education into all corners of the world—using both idealistic success criteria (e.g., maximum number educated, top quality, low cost) as well as practical criteria (e.g., sustainable growth).
225 |
--------------------------------------------------------------------------------
/library/backend/SOLID.md:
--------------------------------------------------------------------------------
1 | # IxDF's SOLID Principles for PHP
2 |
3 | Five agile principles that should guide you every time you write code.
4 | And I’ll show you how to apply them with PHP.
5 | I’ll try to be the most practical as possible, and providing examples for each casuistic.
6 |
7 | 1. **S-RP**: Single Responsibility Principle
8 | 1. **O-CP**: Open Closed Principle
9 | 1. **L-SP**: Liskov Substitution Principle
10 | 1. **I-SP**: Interface Segregation Principle
11 | 1. **D-IP**: Dependency Inversion Principle
12 |
13 | ## Single Responsibility Principle
14 |
15 | > A class should have one, and only one, reason to change.
16 |
17 | **This principle is about actors and high level architecture**.
18 | It specifies that a class (or method) must have a specific purpose, ie, a unique responsibility or a reason to change.
19 |
20 | ### Example
21 |
22 | Imagine that we have an interface for reports like this one:
23 |
24 | ```php
25 | interface Report
26 | {
27 | public function getTitle();
28 | public function getDate();
29 | public function getHeaders();
30 | public function getBody();
31 | public function toCSV();
32 | public function toHTML($name);
33 | }
34 | ```
35 |
36 | This interface has two overlapped responsibilities coexisting here: get data and format it.
37 | What if product owner will ask you to support to formats: XML, JSON, PDF?
38 |
39 | This issue could be solved by using two interfaces: `Report` and `ReportFormatter`.
40 |
41 | ```php
42 | interface Report
43 | {
44 | public function getTitle();
45 | public function getDate();
46 | public function getHeaders();
47 | public function getBody();
48 | }
49 |
50 | interface ReportFormatter
51 | {
52 | public function format(Report $report);
53 | }
54 |
55 | class HtmlReportFormatter implements ReportFormatter
56 | {
57 | public function format(Report $report)
58 | {
59 | $output = '';
60 | // ...
61 |
62 | return $output;
63 | }
64 | }
65 | ```
66 |
67 | ### Conclusion
68 |
69 | This principle is often ignored for reasons of practicality and ease of development,
70 | but if you work on large-scale projects, it’s extremely important to respect the pillars of good OOP design,
71 | or we will lose the battle against complexity.
72 |
73 | ## Open Closed Principle
74 |
75 | > You should be able to extend a classes behavior, without modifying it.
76 |
77 | **This principle is about class design and feature extensions**, it based on delegating responsibility to the class.
78 | If we have actions that depend on the subtype of a class, it is easier to provide that feature in the parent class,
79 | and then the subclasses can (re)implement that feature.
80 |
81 | ### Example
82 |
83 | Let’s see it clearer with the example.
84 |
85 | Imagine we have a Board class that contains Rectangles and can calculate the area of the Rectangles.
86 |
87 | ```php
88 | class Rectangle
89 | {
90 | public $width;
91 | public $height;
92 | }
93 |
94 | class Board
95 | {
96 | public $rectangles = [];
97 |
98 | // ...
99 |
100 | public function calculateArea()
101 | {
102 | $area = 0;
103 | foreach ($this->rectangles as $rectangle) {
104 | $area += $rectangle->width * $rectangle->height;
105 | }
106 |
107 | return $area;
108 | }
109 | }
110 | ```
111 |
112 | But now, our client needs to add circles to the board.
113 |
114 | We have to make our Board to know about Rectangles and Circles,
115 | but if we would respect OCP, we should not need to touch Board or Rectangle.
116 | We should reuse the existing Board and apply it to Circle.
117 |
118 | ```php
119 | interface Shape
120 | {
121 | public function area();
122 | }
123 |
124 | class Rectangle implements Shape
125 | {
126 | // ...
127 |
128 | public function area()
129 | {
130 | return $this->width * $this->height;
131 | }
132 | }
133 |
134 | class Circle implements Shape
135 | {
136 | // ...
137 |
138 | public function area()
139 | {
140 | return $this->radius * $this->radius * pi();
141 | }
142 | }
143 |
144 | class Board
145 | {
146 | public $shapes = [];
147 |
148 | // ...
149 |
150 | public function calculateArea()
151 | {
152 | $area = 0;
153 | foreach ($this->shapes as $shape) {
154 | $area+= $shape->area();
155 | }
156 |
157 | return $area;
158 | }
159 | }
160 | ```
161 |
162 | ### Conclusion
163 |
164 | **Abstraction is a key**. In many ways this principle is at the heart of object oriented design.
165 |
166 | This is what [Robert Martin wrote](https://blog.8thlight.com/uncle-bob/2014/05/12/TheOpenClosedPrinciple.html) about OCP:
167 |
168 | > I’ve heard it said that the OCP is wrong, unworkable, impractical, and not for real programmers with real work to do.
169 | > The rise of plugin architectures makes it plain that these views are utter nonsense.
170 | > On the contrary, a strong plugin architecture is likely to be the most important aspect of future software systems.
171 |
172 | ## Liskov Substitution Principle
173 |
174 | > Derived classes must be substitutable for their base classes.
175 |
176 | This principle says that every class that inherit from a parent class, must not replicate functionality already implemented in the parent class.
177 | Then the parent class should be able to be replaced by any of its subclasses in any region of the code.
178 |
179 | In this case, we have our class Rectangle, and now we want to create a class Square that extends from Rectangle.
180 |
181 | ```php
182 | class Rectangle
183 | {
184 | protected int $height;
185 | protected int $width;
186 |
187 | public function setWidth($w) { $this->width = $w; }
188 | public function setHeight($h) { $this->height = $h; }
189 | public function getArea() { return $this->height * $this->width; }
190 | }
191 |
192 | class Square extends Rectangle
193 | {
194 | public function setWidth($w) { $this->width = $w; $this->height = $w; }
195 | public function setHeight($h) { $this->height = $h; $this->width = $h; }
196 | }
197 | ```
198 |
199 | and we create our function to calculate classes :
200 |
201 | ```php
202 | function areaOfRectangle() {
203 | $rectangle = new Rectangle();
204 | $rectangle->setWidth(7);
205 | $rectangle->setHeight(3);
206 | $rectangle->getArea(); // 21
207 | }
208 | ```
209 |
210 | as the LSP says, we should be able to change Rectangle by Square
211 |
212 | ```php
213 | function areaOfRectangle() {
214 | $rectangle = new Square();
215 | $rectangle->setWidth(7);
216 | $rectangle->setHeight(3);
217 | $rectangle->getArea(); // 9
218 | }
219 | ```
220 |
221 | Remember what we said: “we must make sure that Square classes are extending the Rectangle without changing their behavior”. But, as you can see, 21 is not equal to 9.
222 |
223 | The solution would be to manage the class inheritance hierarchies correctly, for example by introducing the interface `Quadrilateral`.
224 |
225 | ```php
226 | interface Quadrilateral
227 | {
228 | public function setHeight($h);
229 | public function setWidth($w);
230 | public function getArea();
231 | }
232 |
233 | class Rectangle implements Quadrilateral {}
234 |
235 | class Square implements Quadrilateral {}
236 | ```
237 |
238 | ### Conclusion
239 |
240 | Following the Liskov Substitution Principle is a good indicator that you are following a correctly hierarchy schema.
241 | And if you don’t follow it, the unit tests for the superclass would never succeed for the subclasses.
242 |
243 | ## Interface Segregation Principle
244 |
245 | > Make fine grained interfaces that are client specific.
246 |
247 | This principle proposes to divide interfaces so they are more specific.
248 | A class can implement multiple interfaces simultaneously, we shouldn’t force clients to deploy methods unnecessary.
249 |
250 | Let’s think about a digital agency that has workers, so I create the interface Worker
251 |
252 | ```php
253 | interface Worker {
254 | public function takeBreak();
255 | public function code();
256 | public function callToClient();
257 | public function attendMeetings();
258 | public function getPaid();
259 | }
260 | ```
261 |
262 | but for example, if we create the class `Manager` and the class `Developer` we are going to have problems with unused methods:
263 |
264 | ```php
265 | class Manager implements Worker
266 | {
267 | public function code() { return false; }
268 | }
269 |
270 | class Developer implements Worker
271 | {
272 | public function callToClient() { echo $swearWord; }
273 | }
274 | ```
275 |
276 | Then we should create more interfaces.
277 |
278 | ```php
279 | interface Worker
280 | {
281 | public function takeBreak();
282 | public function getPaid();
283 | }
284 |
285 | interface Coder {
286 | public function code();
287 | }
288 |
289 | interface ClientFacer {
290 | public function callToClient();
291 | public function attendMeetings();
292 | }
293 |
294 | class Developer implements Worker, Coder {}
295 |
296 | class Manager implements Worker, ClientFacer {}
297 | ```
298 |
299 | ### Conclusion
300 |
301 | The conclusion here is simple, we can end up with a "fat" class with multitudes of methods specific to a variety of different features.
302 | A system may become so coupled at multiple levels that it is no longer possible to make a change in one place without necessitating many additional changes.
303 |
304 | ## Dependency Inversion Principle
305 |
306 | > Depend on abstractions, not on concretions.
307 |
308 | This is one the most important SOLID principles if you follow TDD.
309 | It refers to a specific form of decoupling software modules.
310 | So, if a class uses other classes, the initialization of the objects has to come from outside.
311 |
312 | As this principle could be difficult to understand, lets review what the principle states:
313 |
314 | > High level modules should not depend on low-level modules, both should depend on abstractions.
315 | > Abstractions should not depend on details. Details should depend on abstractions.
316 |
317 | Then, this principle inverts the way some people may think about OOP, dictating that both classes and subclasses must depend on the same abstraction.
318 |
319 | In this case, I’m going to use the Worker example that we used in the previous principle.
320 |
321 | We have the Manager class, which is the high level class, and then a class called Worker.
322 | The Manager can make Workers to work. Let’s see a traditional OO implementation:
323 |
324 | ```php
325 | // Bad example
326 | class Worker
327 | {
328 | public function work() {}
329 | }
330 |
331 | class Manager
332 | {
333 | private $worker;
334 |
335 | public function setWorker(Worker $w)
336 | {
337 | $this->worker = $w;
338 | }
339 |
340 | public function manage()
341 | {
342 | $this->worker->work();
343 | }
344 | }
345 | ```
346 |
347 | Now, we need to add a new kind of specialized workers, we create a new class SpecializedWorker for this.
348 |
349 | ```php
350 | // Bad example
351 | class SpecializedWorker
352 | {
353 | public function work() {}
354 | }
355 | ```
356 |
357 | Now see the cons:
358 |
359 | **We have to modify the Manager class, and some of the functionality of the Manager might be affected.
360 | The unit tests should be redone.**
361 |
362 | If we would have follow the D-IP, we wouldn’t have had these problems.
363 |
364 | ```php
365 | // Good example
366 |
367 | interface Employee
368 | {
369 | public function work();
370 | }
371 |
372 | class Worker implements Employee
373 | {
374 | public function work() {}
375 | }
376 |
377 | class SpecializedWorker implements Employee
378 | {
379 | public function work() {}
380 | }
381 | ```
382 |
383 | ### Conclusion
384 |
385 | The principle of dependency inversion is critically important for the construction of code that is resilient to change.
386 |
387 | ## Final Thoughts
388 |
389 | Using the SOLID principles implies an increased effort.
390 | It will result in more classes and interfaces to maintain.
391 | More complex but more flexible code.
392 | These principles will make our code better and our life as programmers much easier.
393 | Well designed code is easier for programmers to understand.
394 | A lot of these SOLID principles seem to fall out fairly naturally if you practice TDD (or BDD).
395 |
396 | But remember the KISS (Keep It Simple, Stupid), and DRY (Don’t Repeat Yourself) principles. I believe there are no perfect designs, just trade offs, and the SOLID principles can help you evaluate these and achieve a good balance.
397 |
398 | ## Recommended reading
399 |
400 | - [PrinciplesOfOod by Uncle Bob](http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod)
401 | - [Agile Software Development, Principles, Patterns, and Practices](https://www.amazon.com/Software-Development-Principles-Patterns-Practices/dp/0135974445/ref=sr_1_4?s=books&ie=UTF8&qid=1449575781&sr=1-4&keywords=solid+principles) Book by Robert C. Martin.
402 |
403 | PS: This page is based on [this article](https://jokiruiz.com/software/solid-principles-php/).
404 |
405 | 🦄
406 |
--------------------------------------------------------------------------------
/library/backend/conventions--php.md:
--------------------------------------------------------------------------------
1 | # IxDF's PHP conventions
2 |
3 | [[toc]]
4 |
5 | ## Introduction
6 |
7 | IxDF's PHP coding guidelines favor a Java-like approach: less magic, more types.
8 | We prioritize explicit, strongly-typed code to enhance clarity, IDE support, and static analysis capabilities.
9 |
10 | Key principles:
11 |
12 | - Minimize magic, maximize explicitness
13 | - Leverage PHP's type system
14 | - Optimize for IDE and static analyzer support
15 |
16 | This guide assumes familiarity with PHP 8.x features and modern development practices.
17 | It focuses on our specific conventions and rationale, rather than explaining basic concepts.
18 |
19 | ## Code Style and Tools
20 |
21 | IxDF adheres to [PER Coding Style 2.0](https://www.php-fig.org/per/coding-style/),
22 | extended with rules from [Slevomat Coding Standard](https://github.com/slevomat/coding-standard),
23 |
24 | [PHP Coding Standards Fixer](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer) and select guidelines from Spatie's Laravel PHP style guide.
25 |
26 | ### Tools
27 |
28 | IxDF uses automated tools to check our code on CI:
29 |
30 | - [PHP-CS-Fixer](https://cs.symfony.com/) (fast and stable)
31 | - [PHPCS](https://github.com/squizlabs/PHP_CodeSniffer/wiki) (extendable and customizable)
32 | - [Psalm](https://psalm.dev/docs/) (`errorLevel="1"`)
33 | - [PHPStan](https://phpstan.org/user-guide/getting-started) (`level: 8`)
34 | - [Rector](https://github.com/rectorphp/rector)
35 | - [Deptrac](https://qossmic.github.io/deptrac/) (multiple configurations for modules and entire application)
36 | - [composer-dependency-analyser](https://github.com/shipmonk-rnd/composer-dependency-analyser) (checks for unused and shadow dependencies)
37 | - and more...
38 |
39 | ## Types
40 |
41 | ### Strict types
42 |
43 | Use `declare(strict_types=1);` in all files. This catches type-related bugs early and promotes more thoughtful code, resulting in increased stability.
44 |
45 | ### Type declarations
46 |
47 | - Always specify property types (when possible)
48 | - Always specify parameter types (when possible)
49 | - Always use return types (when possible)
50 | - Use `void` for methods that return nothing
51 | - Use `never` for methods that always throw an exception
52 |
53 | ### Type-casting
54 |
55 | Prefer type-casting over dedicated methods for better performance:
56 |
57 | ```php
58 | // GOOD
59 | $score = (int) '7';
60 | $hasMadeAnyProgress = (bool) $this->score;
61 |
62 | // BAD
63 | $score = intval('7');
64 | $hasMadeAnyProgress = boolval($this->score);
65 | ```
66 |
67 | ## Docblocks
68 |
69 | - Avoid docblocks for fully type-hinted methods/functions unless a description is necessary (([Visual noise is real](https://stitcher.io/blog/a-programmers-cognitive-load)))
70 | - Use docblocks to reveal the contents of arrays and collections
71 | - Write docblocks on one line when possible
72 | - Always use fully qualified class names in docblocks
73 |
74 | ```php
75 | // GOOD
76 | final class Foo
77 | {
78 | /** @var list */
79 | private array $urls;
80 |
81 | /** @var \Illuminate\Support\Collection */
82 | private Collection $users;
83 | }
84 | ```
85 |
86 | ### Inheritance and @inheritDoc
87 |
88 | - Use `@inheritDoc` for classes and methods to make inheritance explicit
89 | - For properties, copy the docblock from the parent class/interface instead of using `@inheritDoc`
90 |
91 | ### Traversable Types
92 |
93 | Use advanced PHPDoc syntax to describe traversable types:
94 |
95 | ```php
96 | /** @return list */
97 | /** @return array */
98 | /** @return Collection */
99 | /** @return array{foo: string, optional?: int} */
100 | ```
101 |
102 |
103 | Technical details
104 |
105 | We use IxDF coding-standard package
106 | to enforce setting the type of the key and value in the iterable types
107 | using phpcs with SlevomatCodingStandard.TypeHints.\* rules
108 | (config)
109 |
110 |
111 |
112 | ### Generic Types and Templates
113 |
114 | Use Psalm template annotations for generic types:
115 |
116 | ```php
117 | /**
118 | * @template T of \Illuminate\Notifications\Notification
119 | * @param class-string $notificationFQCN
120 | * @return T
121 | */
122 | protected function initialize(string $notificationFQCN): Notification
123 | {
124 | // Implementation...
125 | }
126 | ```
127 |
128 | ### Additional Resources
129 |
130 | 1. [Union Types vs. Intersection Types](https://medium.com/@ondrejmirtes/union-types-vs-intersection-types-fd44a8eacbb)
131 | 1. [PHPDoc: Typing in Psalm](https://psalm.dev/docs/annotating_code/typing_in_psalm/)
132 | 1. [PHPDoc: Scalar types in Psalm](https://psalm.dev/docs/annotating_code/type_syntax/scalar_types/#trait-string)
133 | 1. [When to declare classes final](https://ocramius.github.io/blog/when-to-declare-classes-final/)
134 | 1. [Proposed PSR for docblocks](https://github.com/php-fig/fig-standards/blob/master/proposed/phpdoc-tags.md)
135 |
136 | ## OOP Practices
137 |
138 | ### Final by default
139 |
140 | Use `final` for classes and `private` for methods [by default](<(https://ocramius.github.io/blog/when-to-declare-classes-final/)>).
141 | This encourages composition, dependency injection, and interface use over inheritance.
142 | Consider the long-term maintainability, especially for public APIs.
143 |
144 | ### Class name resolution
145 |
146 | Use `ClassName::class` instead of hardcoded fully qualified class names.
147 |
148 | ```php
149 | // GOOD
150 | use App\Modules\Payment\Models\Order;
151 | echo Order::class;
152 |
153 | // BAD
154 | echo 'App\Modules\Payment\Models\Order';
155 | ```
156 |
157 | ### Use `self` keyword
158 |
159 | Prefer `self` over the class name for return type hints and instantiation within the class.
160 |
161 | ```php
162 | public static function createFromName(string $name): self
163 | {
164 | return new self($name);
165 | }
166 | ```
167 |
168 | ### Named constructors
169 |
170 | Use named static constructors to create objects with valid state:
171 |
172 | ```php
173 | public static function createFromSignup(AlmostMember $almostMember): self
174 | {
175 | return new self(
176 | $almostMember->company_name,
177 | $almostMember->country
178 | );
179 | }
180 | ```
181 |
182 | Reason: have a robust API that does not allow developers to create objects with invalid state (e.g. missing parameter/dependency).
183 | A great video on this topic: [Marco Pivetta «Extremely defensive PHP»](https://youtu.be/Gl9td0zGLhw?t=1238)
184 |
185 | ### Domain-specific operations
186 |
187 | Encapsulate domain logic in specific methods rather than using generic setters:
188 |
189 | ```php
190 | // GOOD
191 | public function confirmEmailAwaitingConfirmation(): void
192 | {
193 | $this->email = $this->email_awaiting_confirmation;
194 | $this->email_awaiting_confirmation = null;
195 | }
196 |
197 | // BAD
198 | public function setEmail(string $email): self;
199 | ```
200 |
201 | This approach promotes rich domain models and thin controllers/services.
202 |
203 | Want to learn more?
204 |
205 | [](https://www.youtube.com/watch?v=MF0jFKvS4SI)
206 | Read more about [class invariants](https://www.geeksforgeeks.org/what-is-class-invariant/)
207 | for a better understanding of the dangers of modifying class properties from controllers/services.
208 |
209 | ### Enums
210 |
211 | - Use singular names
212 | - Use PascalCase for case names
213 |
214 | ```php
215 | enum Suit
216 | {
217 | case Hearts;
218 | case Diamonds;
219 | case Clubs;
220 | case Spades;
221 | }
222 | ```
223 |
224 | ## Strings
225 |
226 | **TL;DR**: interpolation > `sprintf` > concatenation
227 |
228 | Prefer string interpolation above `sprintf` and the concatenation `.` operator whenever possible.
229 | Always wrap the variables in curly-braces `{}` when using interpolation.
230 |
231 | ```php
232 | // GOOD
233 | $greeting = "Hi, I am {$name}.";
234 |
235 | // BAD (hard to distinguish the variable)
236 | $greeting = "Hi, I am $name.";
237 | // BAD (less readable)
238 | $greeting = 'Hi, I am '.$name.'.';
239 | $greeting = 'Hi, I am ' . $name . '.';
240 | ```
241 |
242 | For more complex cases when there are a lot of variables to concat or when it’s not possible to use string interpolation,
243 | please use `sprintf` function:
244 |
245 | ```php
246 | $debugInfo = sprintf('Current FQCN is %s. Method name is: %s', self::class, __METHOD__);
247 | ```
248 |
249 | ## Comments and Code Clarity
250 |
251 | Comments SHOULD be avoided as much as possible by writing expressive code.
252 | If you do need to use a comment to explain the what, then
253 | [refactor](https://refactoring.guru/refactoring/techniques) the code.
254 | If you need to explain the reason (why), then format the comments as follows:
255 |
256 | ```php
257 | // There should be a space before a single line comment.
258 |
259 | /*
260 | * If you need to explain a lot, you can use a comment block.
261 | * Notice the single * on the first line. Comment blocks don't need to be three
262 | * lines long or three characters shorter than the previous line.
263 | */
264 | ```
265 |
266 | ## Exceptions
267 |
268 | ### Exception Naming
269 |
270 | Avoid the "Exception" suffix in exception class names. This encourages more descriptive naming.
271 | For details, see [The "Exception" suffix](https://mnapoli.fr/approaching-coding-style-rationally/#:~:text=The%20%22Exception%22%20suffix).
272 |
273 | ::: tip Internal docs
274 | [More info about exceptions](https://github.com/InteractionDesignFoundation/IxDF-web/blob/main/app/Exceptions/README.md).
275 | :::
276 |
277 | ### assert() vs throw
278 |
279 | - Use `assert()` for conditions that should be logically impossible to be false, based on your own code's inputs.
280 | - Use exceptions for checks based on external inputs.
281 | - Treat `assert()` as a debugging tool and type specification aid, not for runtime checks.
282 | - Consider adding a description to `assert()` for clarity (2nd arg).
283 |
284 | Remember: `assert()` may be disabled in production. Use exceptions for critical runtime checks.
285 |
286 | For more information:
287 |
288 | - [PHP assert() documentation](https://www.php.net/manual/en/function.assert.php)
289 | - [Assertions and assertion libraries](https://matthiasnoback.nl/2018/09/assertions-and-assertion-libraries/)
290 |
291 | > Assertions should be used as a debugging feature only.
292 | > You may use them for sanity-checks that test for conditions that should always be true
293 | > and that indicate some programming errors if not or to check for the presence of certain features
294 | > like extension functions or certain system limits and features.
295 |
296 | ::: info Internal docs 🔒
297 | Current status of `assert()` on production: **ENABLED** (see [infrastructure/php/8.3/production/fpm/php.ini](https://github.com/InteractionDesignFoundation/IxDF-web/blob/main/infrastructure/php/production/8.3/fpm/php.ini#L1606)), reasons: [#19772](https://github.com/InteractionDesignFoundation/IxDF-web/issues/19772).
298 | :::
299 |
300 | - [assert on php.net](https://www.php.net/manual/en/function.assert.php)
301 | - [Should I be using assert in my PHP code?](https://stackoverflow.com/questions/4516419/should-i-be-using-assert-in-my-php-code)
302 | - [Assertions and assertion libraries](https://matthiasnoback.nl/2018/09/assertions-and-assertion-libraries/)
303 |
304 | ## Regular Expressions
305 |
306 | Prioritize regex readability. For guidance, refer to [Writing better Regular Expressions in PHP](https://php.watch/articles/php-regex-readability).
307 |
308 | Use `DEFINE` for recurring patterns and `sprintf` for reusable definitions:
309 |
310 | ```php
311 | final class RegexHelper
312 | {
313 | /** @return array */
314 | public function images(string $htmlContent): array
315 | {
316 | $pattern = '
317 | (?'image' # Capture named group
318 | (?P>img) # Recurse img subpattern from definitions
319 | )
320 | ';
321 |
322 | preg_match_all($this->createRegex($pattern), $htmlContent, $matches);
323 |
324 | return $matches['image'];
325 | }
326 |
327 | private function createRegex(string $pattern): string
328 | {
329 | return sprintf($this->getDefinitions(), preg_quote($pattern, '~'));
330 | }
331 |
332 | private function getDefinitions(): string
333 | {
334 | return "~
335 | (?(DEFINE) # Allows defining reusable patterns
336 | (?'attr'(?:\s[^>]++)?) # Capture HTML attributes
337 | (?'img'params)>) # Capture HTML img tag with its attributes
338 | )
339 | %s #Allows adding dynamic regex using sprintf
340 | ~ix";
341 | }
342 | }
343 | ```
344 |
345 | Use [Regex101](https://regex101.com/) for testing patterns.
346 |
347 | > [!TIP]
348 | > There is a less popular, hidden PHP germ [`sscanf`](https://www.php.net/manual/en/function.sscanf.php) function
349 | > that can be used for parsing strings and simplify your code in some cases.
350 |
351 | ## Performance Considerations
352 |
353 | ### Functions
354 |
355 | - Prefer type-casting over type conversion functions (e.g., `(int)$value` instead of `intval($value)`)
356 | - Use `isset()` or `array_key_exists()` instead of `in_array()` for large arrays when checking for key existence
357 | - Leverage opcache for production environments
358 | - Use `stripos()` instead of `strpos()` with `strtolower()` for case-insensitive string searches
359 | - Consider using `array_column()` for extracting specific columns from multidimensional arrays
360 |
361 | For in-depth performance analysis, use tools like Blackfire, XHProf, or Xdebug and Clockwork in development.
362 |
363 | ### Configs
364 |
365 | - Use `opcache` for production environments
366 | - Use PHP in worker code (FrankenPHP, RoadRunner, Swoole) for high-performance applications
367 | - If you use PHP-FPM: [Mateus Guimarães: Optimizing PHP applications for performance](https://mateusguimaraes.com/posts/optimizing-php-applications-for-performance)
368 |
369 | ## Testing and Quality Assurance
370 |
371 | There is a great guide [Testing tips by Kamil Ruczyński](https://github.com/sarven/unit-testing-tips).
372 |
373 | ## Security
374 |
375 | See [Security](./conventions--laravel#security) section from Laravel conventions.
376 |
377 | ## Dependency Management
378 |
379 | - Use Composer for managing PHP dependencies
380 | - Keep `composer.json` and `composer.lock` in version control
381 | - Specify exact versions or version ranges for production dependencies
382 | - Use `composer update` sparingly in production environments
383 | - Regularly update dependencies and review changelogs
384 | - Leverage tools to check for unused and shadow dependencies (`composer-dependency-analyser` or `composer-unused` + `composer-require-checker`)
385 | - Consider using [`composer-normalize`](https://github.com/ergebnis/composer-normalize) for consistent `composer.json` formatting
386 | - Use private repositories or artifact repositories for internal packages
387 | - Implement a dependency security scanning tool in your CI pipeline (e.g., Snyk, Sonatype, or GitHub's Dependabot; add `composer audit` to you CI pipeline)
388 |
389 | 🦄
390 |
--------------------------------------------------------------------------------
/.vitepress/theme/style.css:
--------------------------------------------------------------------------------
1 | /**
2 | * Customize default theme styling by overriding CSS variables:
3 | * https://github.com/vuejs/vitepress/blob/main/src/client/theme-default/styles/vars.css
4 | */
5 |
6 | /**
7 | * Variables
8 | * -------------------------------------------------------------------------- */
9 |
10 | :root {
11 | --vp-c-brand: #009cde;
12 | --vp-c-brand-light: #747bff;
13 | --vp-c-brand-lighter: #9499ff;
14 | --vp-c-brand-lightest: #bcc0ff;
15 | --vp-c-brand-dark: #535bf2;
16 | --vp-c-brand-darker: #454ce1;
17 | --vp-c-brand-dimm: rgba(100, 108, 255, 0.08);
18 | }
19 |
20 | :root{
21 | /* Temp CSS variables: Remove after Tailwind */
22 | --font-size-default: 18px;
23 | --font-size-mobile-default: 16px;
24 | --font-size-print-default: 12px;
25 | --line-height-default: 1.5;
26 |
27 | /* Font families */
28 | --font-serif: 'Merriweather', georgia, serif;
29 | --font-sans-serif: 'Source Sans Pro', arial, sans-serif;
30 | --font-monospace: 'Source Code Pro', monospace;
31 |
32 | /* Font sizes */
33 | --font-size-peta: 3.04rem;
34 | --font-size-tera: 2.44rem;
35 | --font-size-giga: 1.95rem;
36 | --font-size-mega: 1.56rem;
37 | --font-size-kilo: 1.25rem;
38 | --font-size-hecto: 1rem;
39 | --font-size-centi: .8rem;
40 | --font-size-milli: .64rem;
41 |
42 | /* Neutral colors */
43 | --neutral-01: rgb(255 255 255);
44 | --neutral-02: rgb(249 249 249);
45 | --neutral-03: rgb(236 236 236);
46 | --neutral-04: rgb(188 188 188);
47 | --neutral-05: rgb(106 106 106);
48 | --neutral-06: rgb(43 43 43);
49 | --neutral-07: rgb(0 0 0);
50 |
51 | /* Brand colors */
52 | --brand-01: rgb(0 156 222);
53 | --brand-02: rgb(13 111 180);
54 | --accent-01: rgb(69 114 5);
55 | --accent-02: rgb(245 133 30);
56 | --accent-03: rgb(210 31 24);
57 | --accent-04: rgb(128 0 128);
58 | --accent-05: rgb(207 109 200);
59 |
60 | /* Shadow colors */
61 | --shadow-color-default: rgb(106 106 106 / 50%);
62 | --shadow-color-brand-01: rgb(0 123 171 / 50%);
63 | --shadow-color-accent-03: rgb(158 24 19 / 50%);
64 | --shadow-color-neutral-04: rgb(188 188 188 / 50%);
65 | --shadow-color-neutral-06: rgb(43 43 43 / 70%);
66 |
67 | /* External shadow colors */
68 | --shadow-color-facebook: rgb(38 59 99 / 50%);
69 | --shadow-color-twitter: rgb(46 128 191 / 50%);
70 | --shadow-color-linkedin: rgb(0 87 130 / 50%);
71 |
72 | /* Text colors */
73 | --text-color: var(--neutral-06);
74 | --text-color-secondary: var(--neutral-05);
75 | --text-color-inverted: var(--neutral-01);
76 |
77 | /* Link colors */
78 | --link-color: var(--brand-02);
79 | --link-color-visited: var(--accent-04);
80 |
81 | /** Brands Colors */
82 | --brand-color-facebook: rgb(59 89 152);
83 | --brand-color-instagram: rgb(81 127 164);
84 | --brand-color-linkedin: rgb(0 123 182);
85 | --brand-color-pinterest: rgb(203 32 39);
86 | --brand-color-twitter: rgb(56 161 243);
87 | --brand-color-buffer-bg: rgb(50 59 67);
88 | /* Old colors */
89 | --color-hover-gray: rgb(244 244 244);
90 | --color-light-gray: rgb(221 221 221);
91 |
92 | /* Overlaycolors */
93 | --hero-overlay-color: rgb(0 0 0 / 80%);
94 | --hero-overlay-color-small-screen: rgb(0 0 0 / 60%);
95 |
96 | /* This used by elements that match background, allows us to change it with background */
97 | --section-background-color: var(--neutral-02);
98 |
99 | /* Similar to --section-background-color but is used for contrast. Used in things like infoBox */
100 | --contrast-section-background-color: var(--neutral-03);
101 |
102 | /* Border radius */
103 | --border-radius-small: 2px;
104 | --border-radius: 3px;
105 | --border-radius-medium: 5px;
106 | --border-radius-large: 8px;
107 | }
108 |
109 | html:root {
110 | --vp-nav-height: 58px;
111 |
112 | /* vp-default theme overrides */
113 | --vp-c-brand-1: var(--brand-02);
114 | --vp-c-brand-2: rgb(86 154 203);
115 |
116 | /* Overwrite tool tip styles */
117 | --vp-custom-block-tip-border: transparent;
118 | --vp-custom-block-tip-text: inhrit;
119 | --vp-custom-block-tip-bg: var(--neutral-02);
120 |
121 | /* Code block overwrites */
122 | --vp-code-block-bg: var(--neutral-02);
123 | }
124 |
125 | /**
126 | * Component: Button
127 | * -------------------------------------------------------------------------- */
128 |
129 | :root {
130 | --vp-button-brand-border: var(--vp-c-brand-light);
131 | --vp-button-brand-text: var(--vp-c-white);
132 | --vp-button-brand-bg: var(--vp-c-brand);
133 | --vp-button-brand-hover-border: var(--vp-c-brand-light);
134 | --vp-button-brand-hover-text: var(--vp-c-white);
135 | --vp-button-brand-hover-bg: var(--vp-c-brand-light);
136 | --vp-button-brand-active-border: var(--vp-c-brand-light);
137 | --vp-button-brand-active-text: var(--vp-c-white);
138 | --vp-button-brand-active-bg: var(--vp-button-brand-bg);
139 | }
140 |
141 | /* .vitepress/theme/custom.css */
142 | :root {
143 | --font-serif: 'Merriweather', georgia, serif;
144 | --font-sans-serif: 'Source Sans Pro', arial, sans-serif;
145 | --font-monospace: 'Source Code Pro', monospace;
146 | --vp-font-family-base: var(--font-sans-serif); /* normal text font */
147 | --vp-font-family-mono: var(--font-monospace); /* code font */
148 | }
149 |
150 | /**
151 | * Component: Home
152 | * -------------------------------------------------------------------------- */
153 |
154 | :root {
155 | --vp-home-hero-name-color: transparent;
156 | --vp-home-hero-name-background: -webkit-linear-gradient(
157 | 120deg,
158 | #bd34fe 30%,
159 | #41d1ff
160 | );
161 |
162 | --vp-home-hero-image-background-image: linear-gradient(
163 | -45deg,
164 | #bd34fe 50%,
165 | #47caff 50%
166 | );
167 | --vp-home-hero-image-filter: blur(40px);
168 | }
169 |
170 | @media (min-width: 640px) {
171 | :root {
172 | --vp-home-hero-image-filter: blur(56px);
173 | }
174 | }
175 |
176 | @media (min-width: 960px) {
177 | :root {
178 | --vp-home-hero-image-filter: blur(72px);
179 | }
180 | }
181 |
182 | /**
183 | * Component: Custom Block
184 | * -------------------------------------------------------------------------- */
185 |
186 | :root {
187 | --vp-custom-block-tip-border: var(--vp-c-brand);
188 | --vp-custom-block-tip-text: var(--vp-c-brand-darker);
189 | --vp-custom-block-tip-bg: var(--vp-c-brand-dimm);
190 | }
191 |
192 | .dark {
193 | --vp-custom-block-tip-border: var(--vp-c-brand);
194 | --vp-custom-block-tip-text: var(--vp-c-brand-lightest);
195 | --vp-custom-block-tip-bg: var(--vp-c-brand-dimm);
196 | }
197 |
198 | /**
199 | * Component: Algolia
200 | * -------------------------------------------------------------------------- */
201 |
202 | .DocSearch {
203 | --docsearch-primary-color: var(--vp-c-brand) !important;
204 | }
205 |
206 | .grid-container {
207 | display: grid;
208 | grid-template-columns: 1fr 1fr; /* Defines two columns of equal width */
209 | gap: 32px; /* Optional, defines the space between columns */
210 | }
211 |
212 | .ixdf-zen-code {
213 | position: relative;
214 | width: 100%; /* or any specific width */
215 | height: 100%; /* or any specific height */
216 | overflow: hidden; /* ensures the pseudo-element does not overflow */
217 | }
218 |
219 | .zen-section {
220 | text-justify: inter-word;
221 | }
222 |
223 | html .VPHomeHero{
224 | display: flex;
225 | justify-content: center;
226 | align-items: center;
227 |
228 | .container {
229 | width: auto;
230 | margin: 0
231 | }
232 |
233 | &::before {
234 | height: 200px;
235 | width: 200px;
236 | content: '';
237 | background-image: url('https://public-images.interaction-design.org/ixdf-brand/ixdf-logo.svg');
238 | background-position: center center;
239 | background-repeat: no-repeat;
240 | background-size: contain;
241 | margin-right: 32px;
242 | }
243 | }
244 |
245 | html:before {
246 | content: '';
247 | position: fixed;
248 | z-index: -1;
249 | height: 55%;
250 | width: 55%;
251 | max-width: 600px;
252 | max-height: 600px;
253 | min-width: 150px;
254 | min-height: 150px;
255 | right: 0;
256 | bottom: 0;
257 | left: 0;
258 | top: 0;
259 | margin: auto;
260 | background-image: url('https://public-images.interaction-design.org/ixdf-brand/ixdf-logo.svg');
261 | background-position: center center;
262 | background-repeat: no-repeat;
263 | background-size: contain;
264 | opacity: 0.035
265 | }
266 |
267 | @media (max-width: 600px) {
268 | .grid-container {
269 | grid-template-columns: 1fr; /* One column in smaller screens */
270 | }
271 | }
272 |
273 | .link {
274 | font-weight: 500;
275 | color: var(--vp-c-brand-1);
276 | text-decoration: underline;
277 | text-underline-offset: 2px;
278 | transition: color 0.25s, opacity 0.25s;
279 | }
280 |
281 | .appearance {
282 | display: none !important;
283 | }
284 |
285 | /**
286 | * Typography
287 | * -------------------------------------------------------------------------- */
288 | /* TODO: Remove this section after Tailwind */
289 |
290 | html {
291 | font-feature-settings: 'liga', 'clig', 'pnum', 'kern';
292 | font-variant-ligatures: common-ligatures;
293 | text-rendering: optimizeLegibility;
294 | }
295 |
296 | h1,
297 | h2,
298 | h3,
299 | h4,
300 | h5,
301 | h6,
302 | .h1,
303 | .h2,
304 | .h3,
305 | .h4,
306 | .h5 {
307 | font-family: var(--font-sans-serif);
308 | font-weight: 700;
309 | line-height: 1.2;
310 | }
311 |
312 | html .vp-doc h1,
313 | .content h1 {
314 | font-size: var(--font-size-tera);
315 | letter-spacing: -0.75px;
316 | margin-bottom: 16px;
317 | margin-top: 64px;
318 | }
319 |
320 | html .vp-doc h2,
321 | .content h2 {
322 | font-size: var(--font-size-giga);
323 | letter-spacing: -0.5px;
324 | margin-bottom: 16px;
325 | margin-top: 40px;
326 | }
327 |
328 | html .vp-doc h3,
329 | .content h3 {
330 | font-size: var(--font-size-mega);
331 | letter-spacing: -0.25px;
332 | margin-bottom: 16px;
333 | margin-top: 40px;
334 | }
335 |
336 | html .vp-doc h4,
337 | .content h4 {
338 | font-size: var(--font-size-kilo);
339 | margin-bottom: 16px;
340 | margin-top: 32px;
341 | }
342 |
343 | html .vp-doc h5,
344 | .content h5 {
345 | font-size: var(--font-size-default);
346 | margin-bottom: 8px;
347 | margin-top: 24px;
348 | }
349 |
350 | html .vp-doc h6,
351 | .content h6 {
352 | font-size: var(--font-size-centi);
353 | margin-bottom: 8px;
354 | margin-top: 24px;
355 | }
356 |
357 | html {
358 | -webkit-font-smoothing: antialiased;
359 | -moz-osx-font-smoothing: grayscale;
360 | font-feature-settings: "liga", "clig", "pnum", "kern", "liga", "clig";
361 | font-variant-ligatures: common-ligatures;
362 | text-rendering: optimizeLegibility;
363 | }
364 | p {
365 | font-family: var(--font-serif);
366 | font-size: 1rem;
367 | font-weight: normal;
368 | line-height: 1.78;
369 | max-width: var(--max-text-width-size);
370 | }
371 | li p {
372 | margin-bottom: 0
373 | }
374 |
375 | small {
376 | font-size: .8rem;
377 | letter-spacing: 0.15px;
378 | line-height: 1.2;
379 | }
380 |
381 | kbd {
382 | font-size: .8rem;
383 | font-weight: 500;
384 | }
385 |
386 | code,
387 | pre {
388 | font-size: 0.8rem;
389 | }
390 | html:root {
391 | font-family: var(--font-serif);
392 | font-size: var(--font-size-default);
393 | line-height: var(--line-height-default);
394 | }
395 |
396 | html .vp-doc blockquote > p {
397 | font-size: 1rem;
398 | }
399 |
400 | /**
401 | * Default Theme Modifications
402 | * -------------------------------------------------------------------------- */
403 |
404 | /* Buttons */
405 | .VPButton.medium.ghost,
406 | .VPButton.medium.brand {
407 | font-family: var(--font-sans-serif);
408 | box-shadow: 0 2px 8px rgb(106 106 106 / 40%);
409 | border: solid 1px transparent;
410 | border-radius: var(--border-radius-large);
411 | font-weight: 700;
412 | letter-spacing: 0;
413 | line-height: 1.15;
414 | min-width: 160px;
415 | padding: 12px 24px;
416 | text-align: center;
417 | text-decoration: none;
418 | transition: box-shadow 0.25s cubic-bezier(0.455, 0.03, 0.515, 0.955), transform 0.13s cubic-bezier(0.455, 0.03, 0.515, 0.955);
419 | vertical-align: middle;
420 | box-shadow: none;
421 | background-color: transparent;
422 | border: solid 1px var(--neutral-06);
423 | box-shadow: none;
424 | color: var(--neutral-06);
425 | min-width: unset;
426 | font-size: 1rem;
427 | }
428 | .VPButton.medium.ghost:active {
429 | background-color: var(--neutral-03);
430 | box-shadow: none;
431 | color: var(--neutral-06);
432 | transform: translateY(2px);
433 | }
434 | .VPButton.medium.brand {
435 | background: var(--brand-01);
436 | color: var(--neutral-01);
437 | }
438 | .VPButton.medium.brand:hover {
439 | background: var(--neutral-01);
440 | color: var(--brand-01);
441 | }
442 | .VPButton.medium.ghost:hover, .VPButton.medium.ghost:focus, .VPButton.medium.ghost:active {
443 | color: var(--neutral-07);
444 | text-decoration: none;
445 | }
446 | /* Header */
447 | .VPNavBarMenu .VPNavBarMenuLink{
448 | border-bottom: 2px solid transparent;
449 | color: var(--neutral-06);
450 | font-size: 0.9rem;
451 | font-weight: 500;
452 | text-decoration: none;
453 | }
454 | /* Hero */
455 | .VPHero h1.name span {
456 | -webkit-text-fill-color: unset;
457 | background: unset;
458 | -webkit-background-clip: unset;
459 | color: var(--neutral-07);
460 | }
461 | .VPLink p {
462 | font-family: var(--font-sans-serif)
463 | }
464 |
465 | html .VPNavBarMenu .VPNavBarMenuLink{
466 | border-bottom: 2px solid transparent;
467 | color: var(--neutral-06);
468 | font-size: 0.9rem;
469 | font-weight: 500;
470 | text-decoration: none;
471 | height: 22px; /* Not an ideal solution */
472 | padding: 0;
473 | margin: 0;
474 | margin-left: 1.5rem;
475 | }
476 | html body .VPNavBarMenu .VPNavBarMenuLink.active,
477 | html .VPNavBarMenu .VPNavBarMenuLink:hover{
478 | border-bottom-color: var(--brand-02);
479 | color: var(--neutral-06);
480 | text-decoration: none;
481 | }
482 | html body :is(.vp-external-link-icon,html body .vp-doc a[href*='://'],html body .vp-doc a[target='_blank']):not(.no-icon)::after {
483 | -webkit-mask-image: unset;
484 | mask-image: unset;
485 | width: 15px;
486 | height: 15px;
487 | background: url('data:image/svg+xml,');
488 | }
489 | /* Docs Content */
490 | html .vp-doc {
491 | font-family: var(--font-serif);
492 |
493 | a {
494 | font-weight: inherit;
495 | font-size: inherit;
496 | font-family: inherit;
497 | }
498 |
499 | li {
500 | font-size: 1rem;
501 | font-family: var(--font-serif);
502 | }
503 | p,
504 | li {
505 | line-height: 1.78;
506 | }
507 | }
508 | /* Code Snippets */
509 | html .vp-doc [class*='language-'] > span.lang {
510 | right: 18px;
511 | top: 18px;
512 | }
513 |
514 | /**
515 | * Media Queries
516 | * -------------------------------------------------------------------------- */
517 | @media screen and (max-width:768px) {
518 | .grid-container {
519 | grid-gap: 24px;
520 | }
521 |
522 | html:root{
523 | font-size: var(--font-size-mobile-default);
524 | }
525 | html .VPHomeHero{
526 | flex-direction: column;
527 |
528 | &:before{
529 | margin-right: 0;
530 | }
531 |
532 | .container {
533 | margin-top: 32px;
534 | }
535 |
536 | .actions, .container {
537 | text-align: center;
538 | justify-content: center
539 | }
540 |
541 | .name, .tagline {
542 | width: 100%;
543 | max-width: 100%;
544 | }
545 | }
546 | }
547 |
548 | @media print {
549 | html:root{
550 | font-size: var(--font-size-print-default);
551 | }
552 | }
553 |
--------------------------------------------------------------------------------