Skip to content

Commit

Permalink
Merge pull request #13 from tokenguardio/dev
Browse files Browse the repository at this point in the history
Release 2.0.0
  • Loading branch information
rrozek authored Mar 22, 2024
2 parents 0f588ba + 152f3ba commit ded78bc
Show file tree
Hide file tree
Showing 13 changed files with 320 additions and 63 deletions.
6 changes: 3 additions & 3 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
**/node_modules/
**/dist
node_modules
dist
.git
npm-debug.log
.coverage
.coverage.*
.aws
.aws
33 changes: 8 additions & 25 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,30 +1,13 @@
# First stage: Build the application
FROM node:18-slim as builder
FROM node:18-alpine
RUN mkdir -p /usr/src/node-app && chown -R node:node /usr/src/node-app
WORKDIR /usr/src/node-app
USER node

WORKDIR /app
COPY --chown=node:node package*.json ./

# Copy package.json and package-lock.json files first
COPY package*.json ./

# Install dependencies
RUN npm install

COPY . .

# Build application
COPY --chown=node:node . .
RUN npm run build

# Second stage: Setup the production image
FROM node:16-alpine

WORKDIR /app

# Copy built assets from the builder stage to production image
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/package.json ./package.json
COPY --from=builder /app/node_modules ./node_modules

# Run the server in production mode
CMD npm run server:prod

EXPOSE 8080
CMD ["npm", "run", "server:prod"]

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "dashboard-creator-server",
"version": "1.0.1",
"version": "2.0.0",
"description": "",
"main": "src/server.ts",
"engines": {
Expand Down
1 change: 0 additions & 1 deletion src/components/dashboard/dashboard.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ const createDashboard = async (req: Request, res: Response) => {
res.status(httpStatus.INTERNAL_SERVER_ERROR).send({ message: err.message });
}
};
//

const getAllDashboards = async (req: Request, res: Response) => {
try {
Expand Down
1 change: 1 addition & 0 deletions src/components/dashboard/dashboard.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ interface IWriteDashboard extends Document {
title?: string;
theme?: ITheme;
layout?: ILayoutItem[];
elements?: IDashboardElement[];
}

export { IDashboard, ILayoutItem, ITheme, IWriteDashboard };
2 changes: 1 addition & 1 deletion src/components/dashboard/dashboard.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ const themeSchema = new mongoose.Schema<ITheme>({
const dashboardSchema = new mongoose.Schema<IDashboard & Document>({
title: { type: String, required: true },
elements: [{ type: mongoose.Schema.Types.ObjectId, ref: 'DashboardElement' }],
filters: [{type: mongoose.Schema.Types.ObjectId, ref: 'DashboardFilter'}],
filters: [{ type: mongoose.Schema.Types.ObjectId, ref: 'DashboardFilter' }],
layout: [layoutSchema],
theme: themeSchema,
});
Expand Down
95 changes: 79 additions & 16 deletions src/components/dashboard/dashboard.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,28 @@ import { IDashboardElement } from '@components/dashboard/dashboardElement/dashbo
import { IDashboardFilter } from './dashboardFilter/dashboardFilter.interface';

const create = async (dashboardData: IWriteDashboard): Promise<IDashboard> => {
logger.info(`creating dashboard with data ${JSON.stringify(dashboardData)}`);
const newDashboard = await DashboardModel.create({
elements: [],
layout: [],
filters: [],
...dashboardData,
});
logger.info(`Dashboard created: %O`, newDashboard);
return newDashboard;
logger.info(`Creating dashboard with data: ${JSON.stringify(dashboardData)}`);

try {
const elementIds = await Promise.all(
dashboardData.elements.map(async (element) => {
const createdElement =
await dashboardElementService.createDashboardElement(element);
return createdElement._id;
}),
);

const newDashboard = await DashboardModel.create({
...dashboardData,
elements: elementIds,
});

logger.info(`Dashboard created successfully: %O`, newDashboard);
return newDashboard;
} catch (error) {
logger.error(`Error creating dashboard: %O`, error);
throw error;
}
};

const read = async (
Expand Down Expand Up @@ -71,18 +84,68 @@ const getAll = async (): Promise<IDashboard[]> => {

const update = async (
dashboardId: string,
dashboard: IWriteDashboard,
dashboardData: IWriteDashboard,
): Promise<IDashboard> => {
logger.debug('log dashboard', dashboard);
const updatedDashboard = await DashboardModel.findOneAndUpdate(
{ _id: dashboardId },
dashboard,
// Read existing dashboard data from the database
const existingDashboard = await read(dashboardId);

if (!existingDashboard) {
throw new Error('Dashboard not found');
}

const updatedElementsIds = await Promise.all(
dashboardData.elements.map(async (element) => {
logger.info(`${element.id}`);
const existingElement = existingDashboard.elements.find(
(el) => el.id === element.id,
);

if (existingElement) {
await dashboardElementService.updateDashboardElement(
existingElement._id,
element,
);
return existingElement._id; // Return the ID of existing element
} else {
const newElement = await dashboardElementService.createDashboardElement(
element,
);
return newElement._id; // Return the ID of newly created element
}
}),
);

// Remove missing elements
const removedElementsIds = existingDashboard.elements
.filter(
(element) =>
!dashboardData.elements.some(
(reqElement) => reqElement.id === element.id,
),
)
.map((element) => element._id);

await Promise.all(
removedElementsIds.map(async (elementId) => {
await dashboardElementService.deleteDashboardElement(elementId);
return elementId; // Return the ID of removed element
}),
);

logger.info(`removedElementsIds ${removedElementsIds}`);
logger.info(`updatedElementsIds ${updatedElementsIds}`);
// Update the dashboard
const updatedDashboard = await DashboardModel.findByIdAndUpdate(
dashboardId,
{
...dashboardData,
elements: updatedElementsIds,
},
{ new: true },
);
logger.debug(`log updatedDashboard', ${updatedDashboard}`);

if (!updatedDashboard) {
throw new Error('Dashboard not found');
throw new Error('Failed to update dashboard');
}

logger.debug(`Dashboard updated: %O`, updatedDashboard);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,19 @@ export interface IDashboardElementVis extends IDashboardElement {
| 'pieChart';
}

export interface IDashboardElementBasicQueryMeasure {
columnName: string;
operator: string;
}

export interface IDashboardElementBasicQuery extends IDashboardElementVis {
type: 'basicQuery';
dbname: string;
schema: string;
table: string;
dimension: string;
differential?: string;
measures: string[];
measures: IDashboardElementBasicQueryMeasure[];
}

export interface IDashboardElementCustomQuery extends IDashboardElementVis {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,17 @@ const dashboardElementButtonSchema =

const dashboardElementBasicQuerySchema =
new mongoose.Schema<IDashboardElementBasicQuery>({
dbname: { type: String },
schema: { type: String },
table: { type: String },
dimension: { type: String },
differential: { type: String },
measures: [{ type: String }],
measures: [
{
columnName: { type: String },
operator: { type: String },
},
],
visType: { type: String, required: true },
});

Expand Down
26 changes: 18 additions & 8 deletions src/components/db-api/databaseInfo.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ export const getAllDatabases = async (req: Request, res: Response) => {

export const getAllSchemas = async (req: Request, res: Response) => {
try {
const response = await axios.get(`${API_BASE_URL}/schemas`);
const { dbname } = req.params;
const response = await axios.get(
`${API_BASE_URL}/database/${encodeURIComponent(dbname)}/schemas`,
);
res.status(httpStatus.OK).send({ data: response.data });
} catch (error) {
console.error('Error fetching schemas:', error);
Expand All @@ -32,7 +35,10 @@ export const getAllSchemas = async (req: Request, res: Response) => {

export const getAllTables = async (req: Request, res: Response) => {
try {
const response = await axios.get(`${API_BASE_URL}/tables`);
const { dbname } = req.params;
const response = await axios.get(
`${API_BASE_URL}/database/${encodeURIComponent(dbname)}/tables`,
);
res.status(httpStatus.OK).send({ data: response.data });
} catch (error) {
console.error('Error fetching tables:', error);
Expand All @@ -44,11 +50,13 @@ export const getAllTables = async (req: Request, res: Response) => {

export const getTableColumns = async (req: Request, res: Response) => {
try {
const { schemaName, tableName } = req.params;
const { dbname, schema, table } = req.params;
const response = await axios.get(
`${API_BASE_URL}/tables/${encodeURIComponent(
schemaName,
)}/${encodeURIComponent(tableName)}/columns`,
`${API_BASE_URL}/database/${encodeURIComponent(
dbname,
)}/tables/${encodeURIComponent(schema)}/${encodeURIComponent(
table,
)}/columns`,
);

const processedColumns = response.data.map((column) => {
Expand Down Expand Up @@ -89,7 +97,7 @@ export const getTableColumns = async (req: Request, res: Response) => {

export const generateChartData = async (req: Request, res: Response) => {
try {
const { schema, table } = req.params;
const { dbname, schema, table } = req.params;
const { dimension, measures, differential, filters } = req.body;

logger.debug('measures', measures);
Expand All @@ -107,7 +115,9 @@ export const generateChartData = async (req: Request, res: Response) => {
parsedFilters,
});

const url = `${API_BASE_URL}/group-by-operation/${schema}/${table}`;
const url = `${API_BASE_URL}/group-by-operation/${encodeURIComponent(
dbname,
)}/${encodeURIComponent(schema)}/${encodeURIComponent(table)}`;
const response = await axios.post(url, payload);

const mappedData = chartDataGenerator.formatChartDataResponse(
Expand Down
8 changes: 4 additions & 4 deletions src/components/db-api/databaseInfo.router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@ import {
const router: Router = Router();

router.get('/database-info/databases', getAllDatabases);
router.get('/database-info/schemas', getAllSchemas);
router.get('/database-info/tables', getAllTables);
router.get('/database-info/:dbname/schemas', getAllSchemas);
router.get('/database-info/:dbname/tables', getAllTables);
router.get(
'/database-info/tables/:schemaName/:tableName/columns',
'/database-info/:dbname/tables/:schema/:table/columns',
validate(getTableColumnsValidation),
getTableColumns,
);
router.post(
'/database-info/generate-chart-data/:schema/:table',
'/database-info/generate-chart-data/:dbname/:schema/:table',
validate(generateChartDataValidation),
generateChartData,
);
Expand Down
6 changes: 4 additions & 2 deletions src/components/db-api/databaseInfo.validation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ import { ValidSchema } from '../../middleware/joiValidate';

export const getTableColumnsValidation: ValidSchema = {
params: Joi.object({
schemaName: Joi.string().required(),
tableName: Joi.string().required(),
dbname: Joi.string().required(),
schema: Joi.string().required(),
table: Joi.string().required(),
}),
};

Expand All @@ -28,6 +29,7 @@ const filterColumnSchema = Joi.object({

export const generateChartDataValidation: ValidSchema = {
params: Joi.object({
dbname: Joi.string().required(),
schema: Joi.string().required(),
table: Joi.string().required(),
}),
Expand Down
Loading

0 comments on commit ded78bc

Please sign in to comment.