Skip to content

Commit

Permalink
Growth Fullstack Challenge First Commit
Browse files Browse the repository at this point in the history
  • Loading branch information
gsig123 committed Sep 19, 2024
0 parents commit 93ef1c1
Show file tree
Hide file tree
Showing 38 changed files with 14,917 additions and 0 deletions.
9 changes: 9 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Ignore Metals files
scala-backend/project/metals.sbt

# Ignore other unnecessary development files
.idea/
.vscode/
target/


87 changes: 87 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
# Scala-specific
*.class
*.log


# SBT-specific
dist/*
target/
lib_managed/
src_managed/
project/boot/
project/plugins/project/
.history
.cache
.lib/

# IntelliJ IDEA-specific
.idea/
*.iml
*.iws
*.ipr
out/

# VS Code-specific
.vscode/

# macOS-specific
.DS_Store

# Windows-specific
Thumbs.db

# Metals (Scala language server) specific
.metals/
.bloop/

# Scala Worksheet
*.sc

# Temporary files
*~
*.swp
*.swo

# Application-specific
application.conf

# Logs
logs/

# Database
*.db
*.sqlite

# Environment variables
.env

# Frontend-specific
frontend/node_modules/
frontend/build/
frontend/dist/
frontend/.cache/
frontend/.env.local
frontend/.env.development.local
frontend/.env.test.local
frontend/.env.production.local

nodejs-backend/node_modules

# Backend-specific
backend/target/
backend/project/target/

# Dependency directories
project/project/
project/target/

# Scala 3 specific
.tasty

# Bloop specific
.bsp/

# npm/yarn debug logs
npm-debug.log*
yarn-debug.log*
yarn-error.log*
156 changes: 156 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
# Famly technical challenge: Fullstack Engineer in Growth

TODO

- [ ] Hot reloading Scala project not working

Hi :wave:

This repository contains a technical challenge for a full-stack engineering
role in the Growth department at Famly.

## Expectations

We don't expect you to spend a lot of time on this - no more than 2-3 hours.
If you get stuck on a question or don't manage to finish it within that time limit,
please don't sweat it.

The main purpose of this technical assignment is for us to get a feeling for:

- Your technical abilities
- Your problem solving skills
- Your product sense

In the follow up interview we'll ask you to walk us through your solution,
asking questions along the way. If there are pieces missing, we'll use the
time to discuss potential solutions or potentially do some light
pair programming together. The main purpose here is for us to get a sense
for whether we're a good collaboration match - both for us and for you. We're
also interested in understanding your ability to communicate your ideas while
you're walking us through your solution and potential improvements you'd make
if you'd have more time.

## Instructions

1. Start by forking this repository
2. Decide whether you want to solve the backend parts of this challenge in Scala
or in NodeJS
3. Solve the [exercises](#exercises) below.
4. If you want to write something about your solutions to the exercise,
please do so in the [answers.md](answers.md) file.
5. For each question you answer, please create a commit and push them
to the main branch. Remember to include a helpful commit message.
6. When you're done, send us an email with the link to the forked repository

Feel free to reach out with any questions before starting the challenge via email: <bis@famly.co>

## About this project

This project is a simple web application meant to represent a tiny use case of Famly: The Bill Payer profile. In Famly, a parent that pays for the kids tuition is called a Bill Payer.
In this project, the Bill Payer profile includes some helpful features such as:

- Invoices: List all invoices that the nursery has sent to this parent.
- Payment methods: A bill payer can have 0 or more payment methods. An active payment method is what the nursery uses to charge the
parent.

The data in this web app is meant to be very simple - in real life it's a _little bit more complex than that_.

## How to run this project

This project consists of:

- A Scala backend
- A NodeJS backend
- A React + TypeScript Frontend
- A MySQL database

We've included both a Scala backend and a NodeJS backend so that you can
choose which you prefer to work with.

You can of course run the application any way you want, but if you want to
avoid the hassle of getting all the tools/dependencies installed on your
system, we've prepared a [docker-compose.yml](docker-compose.yml)
file for you so you can simply run the app via:

```sh
# Using the Scala backend
docker-compose --profile scala up --build

# Using the NodeJS backend
docker-compose --profile nodejs up --build

```

> In order for this to work, we recommend installing [Docker Desktop](https://www.docker.com/products/docker-desktop/).
Once everything is up-and-running via docker-compose you can access

**The database at:**

- Host: 127.0.0.1
- Port: 3308
- Username: root
- Password: root

**The frontend at:**

- <http://localhost:3000>

**The backend at:**

- <http://localhost:9000>

When making changes to the code the servers running in Docker will pick up those changes. Once everything is done re-building you should be able to
see your changes by refreshing the page.

**Making changes to the database**

If you need to make changes to the database tables,
you can add migrations in the [migrations](migrations) directory and they will be picked up when running docker-compose. You can also just apply the migrations to the database directly, but if you do, please make sure to
note down the SQL statements in the [answers.md](answers.md) file.

## Exercises

### 1

When a user interacts with the Payment Methods widget, something seems off.
When adding or deleting or activating a payment method the changes are not
reflected until the user refreshes the page.

Please fix this issue, so that updates are reflected right away without
needing to refresh the page.

### 2

A user has reported that when they delete a payment method, sometimes
multiple payment methods are deleted (instead of just the one).

Please debug and fix the underlying issue.

### 3

The Payment Methods widget is missing a critical feature: A parent should
always have at least one active payment method. Otherwise, the nursery cannot
charge the parent for the care.

Unfortunately this is not the case right now. If you delete an active payment method,
you end up with no active payment methods.

Please implement this missing feature to ensure that the nursery can always
charge all their parents.

### 4

A parent has requested to be able to see _when_ each payment method was created
in the Payment Methods widget. This is useful in cases where you have multiple
payment methods with the same name.

Please implement this missing feature.

### 5

For audit reasons, it's important to capture any updates that are made to payment
methods for each parent. We need to capture exactly what changed, when it occurred,
and who made the change.

Please implement this critical missing functionality, so that we'll stay in business!
7 changes: 7 additions & 0 deletions answers.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Expercises - Answers

## Question 1

## Question 2

## Question 3
71 changes: 71 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
version: "3.8"

services:
scala-backend:
build: ./scala-backend
ports:
- "9000:9000"
volumes:
- ./scala-backend:/app
depends_on:
- db
profiles:
- scala
environment:
- CHOKIDAR_USEPOLLING=true # Enable polling for file changes

nodejs-backend:
build: ./nodejs-backend
ports:
- "9000:9000"
depends_on:
- db
profiles:
- nodejs
volumes:
- ./nodejs-backend/:/app
- /app/node_modules
environment:
- CHOKIDAR_USEPOLLING=true
- MYSQL_HOST=db
- MYSQL_USER=root
- MYSQL_PASSWORD=root
- MYSQL_DATABASE=parent_profile

frontend:
build: ./frontend
ports:
- "3000:3000"
volumes:
- ./frontend:/app
- /app/node_modules
environment:
- CHOKIDAR_USEPOLLING=true

db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: parent_profile
ports:
- "3308:3306"
volumes:
- db_data:/var/lib/mysql

migrate:
image: mysql:8.0
command: >
sh -c "
until mysql -h db -uroot -proot -e 'select 1'; do
echo 'Waiting for MySQL to be ready...';
sleep 2;
done;
mysql -h db -uroot -proot parent_profile < /migrations/01-init.sql
"
volumes:
- ./migrations:/migrations
depends_on:
- db

volumes:
db_data:
16 changes: 16 additions & 0 deletions frontend/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# TODO: Use a never version of NodeJS
FROM node:18-alpine

WORKDIR /app

COPY package.json yarn.lock ./
RUN yarn install

COPY . .

RUN yarn build

EXPOSE 3000

CMD ["yarn", "start"]

43 changes: 43 additions & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
{
"name": "parent-profile-frontend",
"version": "0.1.0",
"private": true,
"dependencies": {
"@apollo/client": "^3.5.5",
"@material-ui/core": "^4.12.3",
"@material-ui/icons": "^4.11.2",
"@types/react": "^18.3.4",
"@types/react-dom": "^18.3.0",
"graphql": "^15.5.3",
"react": "18.2.0",
"react-dom": "18.2.0",
"react-router-dom": "^6.0.2",
"react-scripts": "^5.0.1",
"typescript": "^5.5.4"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {}
}
Loading

0 comments on commit 93ef1c1

Please sign in to comment.