CryptOvadya is a platform for creating and managing dashboards of crypto data.
Website - cryptovadya.com
UI repo - CryptOvadya UI
- REST API
- Endpoints for CRUD operations on widgets, dashboards, users (see Main Entities)
- JWT authorization using HttpOnly cookie
- Database connection and migrations
- Integration with CoinGecko API
- NestJS Framework
- TypeScript
- Passport - Used for authorization middleware
- bcrypt - Used for password hashing, and compare given password with hash for authentication
- Sequelize
Check package.json for more 😉
First you need to clone or download the repository.
Then, in the project root directory:
- Run
npm install
to get the npm dependencies - Create .env file and add the environment variables
- Run
npm start
(without live reload) ornpm run start:dev
(with live reload) to run the app in the development mode - Use
npm run db:migrate
to run database migrations, see sequelize-cli to learn how to manage migrations
Widget is a generic entity, it represents a common set of data which you would like to see in the dashboard.
Each widget has a type WidgetType
by which the data to be represented is determined.
In this project we have a single type of widget STAT_CARD
.
STAT_CARD
data gives us information about a single crypto pair.
const WIDGET_TYPES = ['STAT_CARD'] as const;
type WidgetType = typeof WIDGET_TYPES[number]; // compiles to - type WidgetType = 'STAT_CARD'
If you would like to add more widget types, just add them to the WIDGET_TYPES
array.
For each widget type you need to create the corresponding WidgetData
type (e.g. StatCardData
).
StatCardData Example:
type StatCardData = {
baseCurrency: string;
quoteCurrency: string;
value: number;
dayDiffPrecent: number;
};
type WidgetData<T extends WidgetType = WidgetType> = T extends 'STAT_CARD' ? StatCardData : any;
To add new data type extend the ternary expression. For example:
type WidgetData<T extends WidgetType = WidgetType> = T extends 'STAT_CARD' ? StatCardData : 'NEW_TYPE' ? NewTypeData : any;
type Widget<T extends WidgetType = WidgetType> = {
id: number;
dashboardId: number;
type: T;
data: WidgetData<T>;
};
Widget have a generic widget type parameter T
which defaults to all widget types. Then we determine the data prop type with WidgetData<T>
Dashboard have a title and a collection of widgets of all types.
type Dashboard = {
id: number;
userId: string;
title: string;
widgets: Widget[];
};
User can manage a collection of dashboards.
export type User = {
id: string;
email: string;
firstName: string;
lastName: string;
};
CRYPTOVADYA_UI_URL=
DATABASE_DIALECT=
DATABASE_HOST=
DATABASE_PORT=
DATABASE_USERNAME=
DATABASE_PASSWORD=
DATABASE_NAME=
DATABASE_URL=
JWT_SECRET=
SEQUELIZE_LOGGING_FLAG= # 0 or 1
Eyal Ovadya :)
Nest is MIT licensed.