Skip to content

Commit 723778e

Browse files
authored
Merge pull request #2 from GeorgianStan/heroku-deployment
Heroku deployment
2 parents 5eb6a6d + 7ee310b commit 723778e

11 files changed

Lines changed: 161 additions & 64 deletions

File tree

.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ lerna-debug.log*
1414

1515
.development.env
1616
.test.env
17-
.production.env
1817

1918
# OS
2019
.DS_Store

Procfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
web: npm run start:prod

README.md

Lines changed: 127 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,128 @@
1-
# Roamnia-UAT-API
1+
# Romania-UAT-API
22

3-
Navigate to `/documentation` for more information.
3+
The project is a web API for the administrative units on the Romanian territory.
4+
5+
## Other linked materials
6+
7+
- [MDRAP-UAT](http://www.dpfbl.mdrap.ro/harta_judete.html)
8+
- [Coduri Siruta](http://www.123coduri.ro/cauta-in-baza-de-date-coduri-siruta.php?vcodg1=%22%22#nomtop)
9+
10+
# Usage
11+
12+
The API is free to use and it can be found at https://romania-uat-api.herokuapp.com/
13+
14+
Tp access the documentation, navigate to [/documentation](https://romania-uat-api.herokuapp.com/documentation/).
15+
16+
## Rate limit
17+
18+
The current rate limit is set to **200** requests per IP in a **5m** window.
19+
20+
The following headers can be tracked to monitor the usage, if needed.
21+
22+
- `x-ratelimit-limit` - total number of available requests in the defined time period;
23+
- `x-ratelimit-remaining` - the number of requests remained until the reset time;
24+
- `x-ratelimit-reset` - the timestamp in seconds when the usage limit will be reset;
25+
26+
## Example usage
27+
28+
The `/api/v1/uat` endpoint can be used for all the required operations.
29+
This endpoint can query the dataset based on a given [SIRUTA](https://ro.wikipedia.org/wiki/SIRUTA) code or based on the UAT type.
30+
31+
_Example 1_
32+
33+
Get information about **Brasov**.
34+
35+
`https://romania-uat-api.herokuapp.com/api/v1/uat?siruta=83`
36+
37+
```json
38+
[
39+
{
40+
"label": "BRASOV",
41+
"type": 1,
42+
"siruta": 83,
43+
"mnemonic": "BV",
44+
"sirutaUp": 877
45+
}
46+
]
47+
```
48+
49+
_Example 2_
50+
51+
Get all the UATs from within **Brasov**.
52+
53+
`https://romania-uat-api.herokuapp.com/api/v1/uat?sirutaUp=83`
54+
55+
```json
56+
[
57+
{
58+
"label": "HOLBAV",
59+
"type": 5,
60+
"siruta": 42472,
61+
"sirutaUp": 83
62+
},
63+
{
64+
"label": "MUNICIPIUL BRASOV",
65+
"type": 3,
66+
"siruta": 40198,
67+
"sirutaUp": 83
68+
},
69+
{
70+
"label": "MUNICIPIUL CODLEA",
71+
"type": 3,
72+
"siruta": 40241,
73+
"sirutaUp": 83
74+
},
75+
...
76+
...
77+
...
78+
]
79+
```
80+
81+
_Example 3_
82+
83+
Get all the UATs that are of type **JUDET**.
84+
85+
`https://romania-uat-api.herokuapp.com/api/v1/uat?type=1`
86+
87+
```json
88+
[
89+
{
90+
"label": "ALBA",
91+
"type": 1,
92+
"siruta": 10,
93+
"mnemonic": "AB",
94+
"sirutaUp": 877
95+
},
96+
{
97+
"label": "ARAD",
98+
"type": 1,
99+
"siruta": 29,
100+
"mnemonic": "AR",
101+
"sirutaUp": 859
102+
},
103+
{
104+
"label": "ARGES",
105+
"type": 1,
106+
"siruta": 38,
107+
"mnemonic": "AG",
108+
"sirutaUp": 831
109+
},
110+
...
111+
...
112+
...
113+
]
114+
```
115+
116+
# Contributing
117+
118+
Pull requests and stars are always welcome. Please check the guidelines.
119+
120+
# Stay in touch
121+
122+
Author - [Stan Georgian](https://twitter.com/GeorgianStan9)
123+
124+
Discussions - [Discussions Page](https://github.com/GeorgianStan/romania-uat-api/discussions)
125+
126+
# License
127+
128+
This project is licensed under the MIT License.

ReadMe-Developer-Manual.md

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -20,42 +20,37 @@ Now `npx` will now use the local `@nestjs/cli` version from `node_modules`.
2020

2121
## How to run in production
2222

23-
To start the application you need to create a `.production.env` file with the expected variables from `.sample.env`.
24-
This file is not completely required, but the ENV variables from .sampe.env must be present in this environment.
25-
26-
If `.production.env` exists then the application will use the variables present there istead of those set globally in the `process.env`.
23+
**Check if `.production.env` exists and it has the expected variables or if the environment variables from .sample.env are all set.**
2724

2825
```bash
2926
$ nvm use #optional, but the min version of NodeJS should match the version from .nvmrc
3027
$ nvm install(optional)
3128
$ npm ci
32-
$ npm run build:prod
33-
$ # set NODE_ENV to production and execute npm run start:prod
29+
$ npm run build
30+
$ npm run start:prod
3431
```
3532

3633
## How to run in dev
3734

38-
Same as production, but this time the file name must be `.development.test`
35+
**Check if `.development.env` exists and it has the expected variables**
3936

4037
1. Switch to node verison >= the one mentioned in `.nvmrc`
4138
2. Install the dependencies `npm ci` or `npm i`
4239
3. Run in dev mode `npm run start:dev`
4340

4441
## How to run debug
4542

46-
Same as development
43+
**Check if `.development.env` exists and it has the expected variables**
4744

4845
1. Open VSCode
4946
2. All the settings are in `.vscode/launch.json`, so update them if you thing that is required
5047
3. In `Run and Debug` panel, choose and run `Debug App`
5148

52-
## Test E2E
53-
54-
For E2E testing the workflow is the same as `development` or `production` in terms of system variables, but this time the file name must be `.test.env`.
55-
5649
## Other Scripts
5750

5851
`npm run test` - to run all the test files
59-
`test:e2e` - to run only the E2E tests
60-
`npm run lint` - to show linting warning or errors
61-
`npm run lint:fix` - to lint and fix the code
52+
`npm run lint` - to lint the code
53+
54+
# Data
55+
56+
The UAT data can be found in `data` folder in JSON format.

jest.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
module.exports = {
22
preset: 'ts-jest',
33
testEnvironment: 'node',
4-
testPathIgnorePatterns: ['/node_modules/', '.git', '/dist/'],
4+
testPathIgnorePatterns: ['/node_modules/', '.git', 'dist/'],
55
moduleNameMapper: {
66
'src(.*)$': '<rootDir>/src/$1',
77
},

package.json

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
{
22
"name": "romania-uat-api",
3-
"version": "0.0.1",
4-
"description": "",
5-
"author": "",
6-
"private": true,
7-
"license": "UNLICENSED",
3+
"version": "1.0.0",
4+
"description": "Web API for the administrative units on the Romanian territory",
5+
"author": "Stan Georgian",
6+
"license": "MIT",
87
"scripts": {
9-
"prebuild": "rimraf dist",
108
"build": "nest build",
119
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
1210
"start": "nest start",

src/core/config/config.service.ts

Lines changed: 11 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -8,53 +8,33 @@ import { readFileSync, existsSync } from 'fs';
88

99
@Injectable()
1010
export class ConfigService {
11-
#envPath: any;
12-
13-
#nodeEnv: string = process.env.NODE_ENV
11+
private envPath: any;
12+
private readonly nodeEnv: string = process.env.NODE_ENV
1413
? process.env.NODE_ENV.trim()
1514
: undefined;
1615

17-
#envConfig: { [key: string]: string };
18-
19-
/**
20-
* * The .env file may be optional, but the ENV variables are required
21-
* ? This function will check if all the variables from .sample.env are present
22-
*/
23-
#validateConfigVariables = () => {
24-
const pathToSampleFile = resolve(process.cwd(), '.sample.env');
25-
const requiredEnvVars: any = Object.keys(
26-
parse(readFileSync(pathToSampleFile)),
27-
);
28-
29-
requiredEnvVars.forEach((envKey: string) => {
30-
if (this.get(envKey) === undefined) {
31-
throw new Error(`Missing ENV variable ${envKey}`);
32-
}
33-
});
34-
};
35-
16+
private readonly envConfig: { [key: string]: string };
3617
constructor() {
37-
switch (this.#nodeEnv) {
18+
switch (this.nodeEnv) {
3819
case 'test':
39-
this.#envPath = resolve(process.cwd(), '.test.env');
20+
this.envPath = resolve(process.cwd(), '.test.env');
4021
break;
4122
case 'production':
42-
this.#envPath = resolve(process.cwd(), '.production.env');
23+
this.envPath = resolve(process.cwd(), '.production.env');
4324
break;
4425
case 'development':
45-
this.#envPath = resolve(process.cwd(), '.development.env');
26+
this.envPath = resolve(process.cwd(), '.development.env');
4627
break;
4728
default:
4829
throw new Error('Specify the NODE_ENV variable');
4930
}
5031

51-
this.#envConfig =
52-
(existsSync(this.#envPath) && parse(readFileSync(this.#envPath))) || {};
53-
54-
this.#validateConfigVariables();
32+
this.envConfig = existsSync(this.envPath)
33+
? parse(readFileSync(this.envPath))
34+
: {};
5535
}
5636

5737
get(key: string): string {
58-
return this.#envConfig[key] || process.env[key];
38+
return process.env[key] || this.envConfig[key];
5939
}
6040
}

src/core/data/@types/enitity.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ export class UAT {
1717

1818
@ApiProperty({
1919
enum: Object.keys(UATType).filter((_) => !isNaN(Number(_))),
20-
description: `The type of the UAT: ${Object.keys(UATType).filter((_) =>
21-
isNaN(Number(_)),
22-
)}`,
20+
description: `The type of the UAT: ${Object.keys(UATType)
21+
.filter((uatType) => isNaN(Number(uatType)))
22+
.map((uatType) => ` ${uatType}`)}`,
2323
})
2424
type: UATType;
2525

src/main.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ async function bootstrap() {
4444
app.use(
4545
rateLimit({
4646
windowMs: utilsService.stringToMs(
47-
configService.get('WINDOWMS_RATE_LIMIT'), // ? a given IP can make a limited number of request in this x time period
47+
configService.get('WINDOWMS_RATE_LIMIT'),
4848
),
4949
max: parseInt(configService.get('RATE_LIMIT_MAX_REQ')), // ? limit each IP to x requests per windowMs
5050
}),
@@ -73,9 +73,7 @@ async function bootstrap() {
7373
// ? start the server
7474
await app.listen(configService.get('PORT'), () => {
7575
console.log(
76-
`App up in ${configService.get('NODE_ENV')} at PORT: ${configService.get(
77-
'PORT',
78-
)}`,
76+
`app up in ${process.env.NODE_ENV} at ${configService.get('PORT')}`,
7977
);
8078
});
8179
}

src/modules/api-v1/api-v1.service.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ export class ApiV1Service {
4848
return this.#getUATBySirutaUp(payload.sirutaUp);
4949
}
5050

51-
if (payload.type) {
51+
if (payload.type !== null || payload.type !== undefined) {
5252
return this.#getUATByType(payload.type);
5353
}
5454
}

0 commit comments

Comments
 (0)