Skip to content

Commit ba6369b

Browse files
committed
ts ddd sample
0 parents  commit ba6369b

File tree

90 files changed

+8346
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

90 files changed

+8346
-0
lines changed

.env

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# DATABASE
2+
DB_CONNECTION=mysql
3+
DB_HOST=cluster_management_db
4+
# DB_HOST=127.0.0.1
5+
DB_PORT=3306
6+
DB_USERNAME=admin
7+
DB_PASSWORD=admin
8+
DB_DATABASE=cluster_node_management

.eslintrc.js

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
module.exports = {
2+
parser: '@typescript-eslint/parser',
3+
parserOptions: {
4+
project: 'tsconfig.json',
5+
sourceType: 'module',
6+
},
7+
plugins: ['@typescript-eslint/eslint-plugin'],
8+
extends: [
9+
'plugin:@typescript-eslint/recommended',
10+
'plugin:prettier/recommended',
11+
],
12+
root: true,
13+
env: {
14+
node: true,
15+
jest: true,
16+
},
17+
ignorePatterns: ['.eslintrc.js'],
18+
rules: {
19+
'@typescript-eslint/interface-name-prefix': 'off',
20+
'@typescript-eslint/explicit-function-return-type': 'off',
21+
'@typescript-eslint/explicit-module-boundary-types': 'off',
22+
'@typescript-eslint/no-explicit-any': 'off',
23+
},
24+
};

.gitignore

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# compiled output
2+
/dist
3+
/node_modules
4+
5+
# Logs
6+
logs
7+
*.log
8+
npm-debug.log*
9+
yarn-debug.log*
10+
yarn-error.log*
11+
lerna-debug.log*
12+
13+
# OS
14+
.DS_Store
15+
16+
# Tests
17+
/coverage
18+
/.nyc_output
19+
20+
# IDEs and editors
21+
/.idea
22+
.project
23+
.classpath
24+
.c9/
25+
*.launch
26+
.settings/
27+
*.sublime-workspace
28+
29+
# IDE - VSCode
30+
.vscode/*
31+
!.vscode/settings.json
32+
!.vscode/tasks.json
33+
!.vscode/launch.json
34+
!.vscode/extensions.json
35+
36+
docker-compose.override.yaml

.prettierrc

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"printWidth": 120,
3+
"trailingComma": "es5",
4+
"tabWidth": 2,
5+
"semi": false,
6+
"singleQuote": true,
7+
"endOfLine": "lf",
8+
"arrowParens": "avoid"
9+
}

Makefile

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
.DEFAULT_GOAL := help
2+
.SILENT:
3+
4+
## Colors
5+
COLOR_RESET = \033[0m
6+
COLOR_INFO = \033[32m
7+
COLOR_COMMENT = \033[33m
8+
9+
## Help
10+
help:
11+
printf "${COLOR_COMMENT}Usage:${COLOR_RESET}\n"
12+
printf " make [target]\n\n"
13+
printf "${COLOR_COMMENT}Available targets:${COLOR_RESET}\n"
14+
awk '/^[a-zA-Z\-\_0-9\.@]+:/ { \
15+
helpMessage = match(lastLine, /^## (.*)/); \
16+
if (helpMessage) { \
17+
helpCommand = substr($$1, 0, index($$1, ":")); \
18+
helpMessage = substr(lastLine, RSTART + 3, RLENGTH); \
19+
printf " ${COLOR_INFO}%-16s${COLOR_RESET} %s\n", helpCommand, helpMessage; \
20+
} \
21+
} \
22+
{ lastLine = $$0 }' $(MAKEFILE_LIST)
23+
24+
## starts platform
25+
start:
26+
@echo Running \${COLOR_INFO}\`docker-compose up -d\`\${COLOR_RESET} ...
27+
docker-compose up -d
28+
29+
## destroys containers and recreates platform
30+
recreate:
31+
@echo Running \${COLOR_INFO}\`docker-compose down -v --remove-orphans\`\${COLOR_RESET} ...
32+
docker-compose down -v --remove-orphans && make start

README.md

+114
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
# Cluster Node API
2+
3+
## Getting started
4+
5+
### System requirements
6+
7+
- git
8+
- docker
9+
- docker-compose
10+
11+
## Startup
12+
13+
A `Makefile` provides a couple of commands
14+
15+
```shell
16+
$ make
17+
Usage:
18+
make [target]
19+
20+
Available targets:
21+
help: Help
22+
start: starts platform
23+
recreate: destroys containers and recreates platform
24+
```
25+
To startup the project just run `make start`.
26+
Wait a bit for the containers to start and then browse [http://localhost:3000/api](http://localhost:3000/api) and you should see a Swagger UI
27+
28+
![Screenshot](./docs/assets/img.png)
29+
30+
## Authentication
31+
```text
32+
username: john.doe
33+
password: password
34+
```
35+
```shell
36+
curl --request POST 'http://localhost:3000/api/v1/auth/login' \
37+
--header 'Content-Type: application/json' \
38+
--data-raw '{
39+
"username": "john.doe",
40+
"password": "password"
41+
}'
42+
```
43+
44+
it will give an access token that should be used to access other APIs
45+
46+
```shell
47+
{
48+
"access_token": "<THE GENERATED TOKEN>"
49+
}
50+
```
51+
52+
```shell
53+
curl --request GET 'http://localhost:3000/api/v1/<some endpoint>' \
54+
--header 'Authorization: Bearer <THE GENERATED TOKEN>'
55+
```
56+
57+
<details>
58+
<summary>See Assignment document!</summary>
59+
60+
# Interview Assignment - Cluster Node API
61+
62+
Hello, dear candidate! Thanks for taking the time to try this out.
63+
64+
The goal of this assignment is to assert (to some degree) your skills as a software engineer. You should focus on showcasing your skill at coding and problem solving. The solution is intentionally open-ended, to give you space for personal interpretation, but for all intents and purposes you can pretend that you're building a production-ready application!
65+
66+
You can develop the assignment in any common language you can demonstrate being comfortable coding with.
67+
68+
You're **allowed and encouraged** to use third party libraries and tools, as long as they are free and open source. An effective developer knows what to build and what to reuse, but also how his/her tools work. Be prepared to answer some questions about these, like why you chose them and what other alternatives you considered.
69+
70+
As this is a code review process, please minimize generated code, as this might make our jobs as reviewers more difficult.
71+
72+
_Note: While we love open source at SUSE, please do not create a public repo with your assignment in! This test is only shared with people interviewing, and for obvious reasons we'd like it to remain this way._
73+
74+
## Instructions
75+
76+
1. Clone this repository.
77+
2. Create a pull request targeting the master branch of this repository.
78+
This PR should contain setup instructions for your application and a breakdown of the technologies & packages you chose to use, why you chose to use them, and the design decisions you made.
79+
3. Reply to the email thread you're having with our HR department telling them we can start reviewing your code.
80+
81+
## Requirements
82+
83+
Create a simple API to manage nodes of computing clusters.
84+
We'll refer to this as "The API" throughout the rest of this document.
85+
86+
There are two possible types of end users for this API: an unauthenticated one, and an authenticated one. We'll refer to these as "anonymous user" and "privileged user" respectively. The privileged user can implicitly also do everything the anonymous user can.
87+
88+
- As an anonymous user, I shall be able to access The API remotely.
89+
- As an anonymous user, I shall be able to read a list of features The API offers.
90+
- As an anonymous user, I shall be informed when trying to use a feature that is only available to privileged users.
91+
- As a privileged user, I shall be able to search for nodes, either by node name or by cluster name.
92+
- As a privileged user, I shall be able to create/read/update/delete nodes.
93+
- As a privileged user, I shall be able to issue power-on/shutdown/reboot commands to a single node.
94+
95+
### Constraints and details
96+
97+
- The achitectural patterns, protocols and schemas used to implement The API are left as free design decisions.
98+
- The only required entity handled by The API is a cluster _node_. Clusters are not required to be handled as a dedicated entity.
99+
- The state represented by The API obviously doesn't have to be an actual cluster: the _single source of truth_ is expected to be simulated by any mean necessary (filesystem, database, object storage, etc); the only requirement is that such state must be persistent, i.e. restarting The API doesn't clear the data.
100+
- The API itself doesn't _need_ to be "containerized" but, as a developer, I should be able to perform changes to the source code of The API and observe the results, by building/running it, on a Linux system which only provides an OCI container engine, without installing any new packages.
101+
- Additional features you might want to autonomously define and implement are welcome!
102+
103+
104+
## What to expect from the review
105+
106+
The review of your solution will happen in two phases:
107+
1. First, you'll have a chance to interact with the interviewer[s] in a traditional asynchronous code review, like you would do on GitHub every day.
108+
2. After the async peer review is done, we'll schedule a live chat with team, where further in-depth questions might be asked, to give you the chance to meet your potential future colleagues!
109+
110+
## Good luck
111+
112+
Code something awesome!
113+
114+
</details>

docker-compose.override.yaml.dist

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
version: '3.8'
2+
3+
services:
4+
5+
cluster_management_db:
6+
platform: linux/x86_64

docker-compose.yaml

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
version: '3.8'
2+
3+
services:
4+
cluster_management_api:
5+
build:
6+
context: .
7+
dockerfile: ./docker/backend/Dockerfile
8+
ports:
9+
- 3000:3000
10+
volumes:
11+
- ./:/app
12+
depends_on:
13+
- cluster_management_db
14+
command: sh -c "yarn && yarn start:dev"
15+
16+
cluster_management_db:
17+
image: mysql:8.0.25
18+
ports:
19+
- 3306:3306
20+
environment:
21+
- MYSQL_ROOT_PASSWORD=root
22+
- MYSQL_DATABASE=cluster_node_management
23+
- MYSQL_USER=admin
24+
- MYSQL_PASSWORD=admin
25+
volumes:
26+
- cluster_management_db_volume:/var/lib/mysql
27+
- ./docker/mysql/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d:rw
28+
- ./docker/mysql/etc/conf.d/my.cnf:/etc/mysql/conf.d/custom.cnf
29+
30+
volumes:
31+
cluster_management_db_volume:

docker/backend/Dockerfile

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
FROM node:14.17-alpine
2+
3+
RUN mkdir -p /app && \
4+
chown -R node:node /app && \
5+
npm install -g ts-node @nestjs/cli
6+
7+
USER node
8+
9+
WORKDIR /app
10+
11+
COPY --chown=node:node package.json /app
12+
COPY --chown=node:node yarn.lock /app
13+
COPY --chown=node:node tsconfig.json /app
14+
15+
COPY --chown=node:node ./dist /app/dist
16+
# Should we copy the whole project in the image?
17+
18+
RUN yarn install && yarn build
19+
20+
CMD ["node", "./dist/main.js"]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
CREATE TABLE IF NOT EXISTS nodes (
2+
id VARCHAR (36), -- maybe should be something like BINARY or similar
3+
cluster VARCHAR(255) NOT NULL,
4+
`name` VARCHAR(255) NOT NULL,
5+
is_powered_on BOOLEAN DEFAULT 0,
6+
UNIQUE (cluster, `name`),
7+
FULLTEXT idx_node_fulltext(`name`),
8+
PRIMARY KEY (id)
9+
) ENGINE=InnoDB;
10+
11+
INSERT INTO nodes (
12+
id,
13+
cluster,
14+
`name`,
15+
is_powered_on
16+
) VALUES
17+
('dfa7b991-4e02-4fd5-960b-c63899757b83', 'b27f20e0-08d2-4401-8d5a-9f1dd1f1414f', 'node-01', 0),
18+
('e53942ee-4bbe-4027-b2fc-afd18c26c20f', 'b27f20e0-08d2-4401-8d5a-9f1dd1f1414f', 'node-02', 1),
19+
('161c3c62-a3ca-480f-8035-40e340e4ed4c', 'b27f20e0-08d2-4401-8d5a-9f1dd1f1414f', 'node-03', 1),
20+
('a32532b3-f8f6-4563-8562-0ae313a24563', 'b27f20e0-08d2-4401-8d5a-9f1dd1f1414f', 'node-04', 0),
21+
('16e2ef00-daa4-4346-b672-4c7b0e86f2f4', 'b27f20e0-08d2-4401-8d5a-9f1dd1f1414f', 'node-05', 1),
22+
('4d8af223-f3e0-4cfc-9936-63226bad0941', 'b27f20e0-08d2-4401-8d5a-9f1dd1f1414f', 'node-06', 0),
23+
('eba84c8b-d530-44bf-b341-067b76a17bdc', 'e9ad75c2-c8d8-40b8-891d-4a56fd8fa6eb', 'node-01', 1),
24+
('0dd7c8a2-b78e-4375-a155-42544b6f6acd', 'e9ad75c2-c8d8-40b8-891d-4a56fd8fa6eb', 'node-02', 1),
25+
('417db5fc-397a-47ad-869f-4ab65f43a807', 'e9ad75c2-c8d8-40b8-891d-4a56fd8fa6eb', 'node-03', 0),
26+
('30f7e626-e771-4a93-8552-34addd769b42', 'e9ad75c2-c8d8-40b8-891d-4a56fd8fa6eb', 'node-04', 0),
27+
('887229ac-e483-4273-961e-fb523fe68ac3', 'e9ad75c2-c8d8-40b8-891d-4a56fd8fa6eb', 'node-05', 1),
28+
('bb9e1bd9-a558-4c73-af26-4f50df473ffe', 'e9ad75c2-c8d8-40b8-891d-4a56fd8fa6eb', 'node-06', 1);

docker/mysql/etc/conf.d/my.cnf

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
[mysqld]
2+
character-set-server = utf8
3+
collation-server = utf8_unicode_ci
4+
skip-character-set-client-handshake

docs/assets/img.png

181 KB
Loading

nest-cli.json

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"collection": "@nestjs/schematics",
3+
"sourceRoot": "src"
4+
}

0 commit comments

Comments
 (0)