Skip to content

Commit

Permalink
Merge branch 'demo' into prod
Browse files Browse the repository at this point in the history
  • Loading branch information
igor.la committed Dec 18, 2023
2 parents 5a50799 + 27da67c commit a0cbe75
Show file tree
Hide file tree
Showing 121 changed files with 2,259 additions and 1,448 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/deploy-prod.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,6 @@ jobs:
- name: connect and update traefik
run: ssh ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }} "cd ${{ vars.PROD_DIR }} && docker compose --compatibility -p ows-events -f docker-compose.traefik.yml up -d --build && exit"
- name: connect and rebuild services
run: ssh ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }} "export GITHUB_PARSING_TOKEN=${{ secrets.PARSING_TOKEN }} && export SECRET_KEY=${{ secrets.BACKEND_SECRET_KEY }} && export VITE_TELEGRAM_AUTH_BOT_NAME=${{ vars.PROD_AUTH_TELEGRAM_BOT_NAME }} && cd ${{ vars.PROD_DIR }} && docker compose --compatibility -p ows-events_prod -f docker-compose.prod.yml up -d --force-recreate --build && exit"
run: ssh ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }} "export VITE_GTAG_ID=${{ secrets.PROD_GTAG_ID }} && export GITHUB_PARSING_TOKEN=${{ secrets.PARSING_TOKEN }} && export SECRET_KEY=${{ secrets.BACKEND_SECRET_KEY }} && export VITE_TELEGRAM_AUTH_BOT_NAME=${{ vars.PROD_AUTH_TELEGRAM_BOT_NAME }} && cd ${{ vars.PROD_DIR }} && docker compose --compatibility -p ows-events_prod -f docker-compose.prod.yml up -d --force-recreate --build && exit"
- name: cleanup
run: rm -rf ~/.ssh
2 changes: 1 addition & 1 deletion .github/workflows/deploy-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,6 @@ jobs:
- name: connect and update traefik
run: ssh ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }} "cd ${{ vars.TEST_DIR }} && docker compose --compatibility -p ows-events -f docker-compose.traefik.yml up -d --build && exit"
- name: connect and rebuild services
run: ssh ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }} "export GITHUB_PARSING_TOKEN=${{ secrets.PARSING_TOKEN }} && export SECRET_KEY=${{ secrets.BACKEND_SECRET_KEY }} && export VITE_TELEGRAM_AUTH_BOT_NAME=${{ vars.TEST_AUTH_TELEGRAM_BOT_NAME }} && cd ${{ vars.TEST_DIR }} && docker compose --compatibility -p ows-events_test -f docker-compose.test.yml up -d --force-recreate --build && exit"
run: ssh ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }} "export VITE_GTAG_ID=${{ secrets.TEST_GTAG_ID }} && export GITHUB_PARSING_TOKEN=${{ secrets.PARSING_TOKEN }} && export SECRET_KEY=${{ secrets.BACKEND_SECRET_KEY }} && export VITE_TELEGRAM_AUTH_BOT_NAME=${{ vars.TEST_AUTH_TELEGRAM_BOT_NAME }} && cd ${{ vars.TEST_DIR }} && docker compose --compatibility -p ows-events_test -f docker-compose.test.yml up -d --force-recreate --build && exit"
- name: cleanup
run: rm -rf ~/.ssh
43 changes: 25 additions & 18 deletions backend/src/controllers/events-state-controller.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,9 @@
import { v4 as uuid } from 'uuid';
import { FilterQuery } from 'mongoose';
import { EventDbEntity, EventOnPoster } from '@common/types/event';
import { EventDbEntity, EventOnPoster, SearchEventPayload } from '@common/types/event';
import { EventModel } from '../models/event.model';
import { imageController } from './image-controller';

export type FindEventParams = {
searchLine?: string;
city?: string;
country?: string;
};

class EventsStateController {
async addEvent(event: EventOnPoster) {
const id = uuid();
Expand All @@ -25,7 +19,7 @@ class EventsStateController {
return id;
}

async getEvents(query?: FindEventParams | undefined): Promise<EventDbEntity[]> {
async getEvents(query?: SearchEventPayload | undefined): Promise<EventDbEntity[]> {
const queryObject: FilterQuery<EventOnPoster> = {};
if (query?.searchLine) {
queryObject.$text = { $search: query.searchLine };
Expand All @@ -36,19 +30,32 @@ class EventsStateController {
if (query?.city) {
queryObject['location.city'] = query?.city;
}
if (query?.tags && query?.tags.length !== 0) {
queryObject.tags = { $in: query?.tags };
}
queryObject['meta.moderation.status'] = { $nin: ['declined', 'in-progress'] };

const futureEvents = await EventModel.find(
{ ...queryObject, date: { $gt: Date.now() } },
{},
const pipeline = [
{
sort: {
date: 'ascending'
$match: {
...queryObject,
$expr: {
$gte: [
{
$add: ['$date', { $multiply: [1000, '$durationInSeconds'] }]
},
{
$toDouble: '$$NOW'
}
]
}
}
}
).exec();

return futureEvents.map((event) => event.toObject());
];
const futureEvents = await EventModel.aggregate(pipeline)
.sort({ date: 'ascending' })
.exec();
return futureEvents;
}

async getEvent(id: string) {
Expand Down Expand Up @@ -98,8 +105,8 @@ class EventsStateController {
return event;
}

async findAllTags() {
const tags = await EventModel.distinct('tags');
async findUsedTags() {
const tags = await EventModel.distinct('tags', { date: { $gt: Date.now() } });

return tags;
}
Expand Down
3 changes: 2 additions & 1 deletion backend/src/rest/v1/auth/router.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { FastifyInstance } from 'fastify';
import { ITelegramRoute } from './type';
import { telegramLogin } from './controller';
import { telegramSchema } from './schema';

export const authApi = async (fastify: FastifyInstance) => {
fastify.get<ITelegramRoute>('/telegram', telegramLogin);
fastify.get<ITelegramRoute>('/telegram', { schema: telegramSchema, handler: telegramLogin });
};
34 changes: 34 additions & 0 deletions backend/src/rest/v1/auth/schema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
export const telegramSchema = {
description: 'Login/register through telegram',
tags: ['Auth'],
summary: 'Login through telegram',
response: {
302: {
type: 'null',
description: 'Redirect to special page, where token get stored on client side'
}
},
querystring: {
type: 'object',
properties: {
id: {
type: 'string'
},
first_name: {
type: 'string'
},
last_name: {
type: 'string'
},
username: {
type: 'string'
},
photo_url: {
type: 'string'
},
auth_date: {
type: 'number'
}
}
}
};
4 changes: 2 additions & 2 deletions backend/src/rest/v1/events/controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,8 @@ export const updateEvent: IUpdateEventHandler = async (request) => {
};

export const findEvents: IFindEventHandler = async (request) => {
const { searchLine, country, city } = request.body;
const { searchLine, country, city, tags } = request.body;

const events = await eventsStateController.getEvents({ searchLine, country, city });
const events = await eventsStateController.getEvents({ searchLine, country, city, tags });
return events;
};
3 changes: 2 additions & 1 deletion backend/src/rest/v1/events/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,8 @@ export const findEventsSchema = {
properties: {
searchLine: { type: 'string' },
city: { type: 'string' },
country: { type: 'string' }
country: { type: 'string' },
tags: { type: 'array', items: { type: 'string' } }
}
},
security: [{ authJWT: [] }]
Expand Down
5 changes: 2 additions & 3 deletions backend/src/rest/v1/events/type.d.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { EventOnPoster } from '@common/types';
import { EventParams } from '@common/types/event';
import { EventParams, SearchEventPayload } from '@common/types/event';
import { SupportedLanguages } from '../../../../../common/const';
import { FindEventParams } from '../../../controllers/events-state-controller';
import { IRouteHandler } from '../../types';

type IAddEventRoute = {
Expand Down Expand Up @@ -55,7 +54,7 @@ type IFindEventRoute = {
Header: {
'accept-language': SupportedLanguages;
};
Body: FindEventParams;
Body: SearchEventPayload;
Reply: EventOnPoster[];
};
type IFindEventHandler = IRouteHandler<IFindEventRoute>;
6 changes: 5 additions & 1 deletion backend/src/rest/v1/location/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
getCitiesByCountrySchema,
getCountriesSchema,
getMetaSchema,
getUsedCitiesByCountrySchema,
getUsedCountriesSchema
} from './schema';

Expand All @@ -34,5 +35,8 @@ export const locationApi = async (fastify: FastifyInstance) => {
schema: getUsedCountriesSchema,
handler: getUsedCountries
});
fastify.get<IGetCitiesByCountryRouteProps>('/usedCities/:country', getUsedCities);
fastify.get<IGetCitiesByCountryRouteProps>('/usedCities/:country', {
schema: getUsedCitiesByCountrySchema,
handler: getUsedCities
});
};
18 changes: 18 additions & 0 deletions backend/src/rest/v1/location/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,21 @@ export const getUsedCountriesSchema = {
}
}
};

export const getUsedCitiesByCountrySchema = {
description: 'get used cities by country',
tags: ['Location'],
summary: 'Get used cities by country',
params: {
type: 'object',
properties: {
country: { type: 'string' }
}
},
response: {
200: {
type: 'array',
items: { type: 'string' }
}
}
};
13 changes: 10 additions & 3 deletions backend/src/rest/v1/moderation/router.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
import { FastifyInstance } from 'fastify';
import { approve, decline, get } from './controller';
import { IApproveEventRoute, IDeclineEventRoute, IGetEventsRoute } from './types';
import { approveEventSchema, declineEventSchema, getEventsByStatusSchema } from './schema';

export const manualModerationApi = async (fastify: FastifyInstance) => {
fastify.get<IGetEventsRoute>('/get/:status', get);
fastify.get<IGetEventsRoute>('/get/:status', { schema: getEventsByStatusSchema, handler: get });

fastify.get<IApproveEventRoute>('/approve/:eventId', approve);
fastify.get<IApproveEventRoute>('/approve/:eventId', {
schema: approveEventSchema,
handler: approve
});

fastify.get<IDeclineEventRoute>('/decline/:eventId', decline);
fastify.get<IDeclineEventRoute>('/decline/:eventId', {
schema: declineEventSchema,
handler: decline
});
};
43 changes: 43 additions & 0 deletions backend/src/rest/v1/moderation/schema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { ItemEvent } from '../events/schema';

export const getEventsByStatusSchema = {
description: 'get events by moderation status',
tags: ['Moderation'],
summary: 'Get events by moderation status',
params: {
type: 'object',
properties: {
country: { type: 'string' }
}
},
response: {
200: {
type: 'array',
items: ItemEvent
}
}
};

export const approveEventSchema = {
description: 'approve event',
tags: ['Moderation'],
summary: 'Approve event',
params: {
type: 'object',
properties: {
eventId: { type: 'string' }
}
}
};

export const declineEventSchema = {
description: 'decline event',
tags: ['Moderation'],
summary: 'Decline event',
params: {
type: 'object',
properties: {
eventId: { type: 'string' }
}
}
};
78 changes: 39 additions & 39 deletions backend/src/rest/v1/tags/controller.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,32 @@
import jwt from 'jsonwebtoken';
// import jwt from 'jsonwebtoken';
import { CommonErrorsEnum } from '../../../../../common/const';
import { eventsStateController } from '../../../controllers/events-state-controller';
import {
IAddTagHandler,
IGetAllTagsHandler,
IGetTagByEventHandler,
IDeleteTagsHandler
// IAddTagHandler,
IGetUsedTagsHandler,
IGetTagByEventHandler
// IDeleteTagsHandler
} from './type';
import { ITokenData } from '../../types';
import { vars } from '../../../config/vars';

export const addTags: IAddTagHandler = async (request) => {
const { event } = request.body;
if (!event) throw new Error(CommonErrorsEnum.NO_PAYLOAD_PROVIDED);
const token = request.headers.authorization;
if (!token) throw new Error(CommonErrorsEnum.UNAUTHORIZED);

const jwtData = jwt.verify(token, vars.secret) as ITokenData;
if (!jwtData.id) throw new Error(CommonErrorsEnum.WRONG_TOKEN);

event.creatorId = jwtData.id;
const response = await eventsStateController.addTags(event);

return { newtag: response };
};

export const getAllTags: IGetAllTagsHandler = async () => {
const response = await eventsStateController.findAllTags();
// import { ITokenData } from '../../types';
// import { vars } from '../../../config/vars';

// export const addTags: IAddTagHandler = async (request) => {
// const { event } = request.body;
// if (!event) throw new Error(CommonErrorsEnum.NO_PAYLOAD_PROVIDED);
// const token = request.headers.authorization;
// if (!token) throw new Error(CommonErrorsEnum.UNAUTHORIZED);
//
// const jwtData = jwt.verify(token, vars.secret) as ITokenData;
// if (!jwtData.id) throw new Error(CommonErrorsEnum.WRONG_TOKEN);
//
// event.creatorId = jwtData.id;
// const response = await eventsStateController.addTags(event);
//
// return { newtag: response };
// };

export const getUsedTags: IGetUsedTagsHandler = async () => {
const response = await eventsStateController.findUsedTags();

return response;
};
Expand All @@ -39,17 +39,17 @@ export const getTagByEventId: IGetTagByEventHandler = async (request) => {
return response;
};

export const deleteTag: IDeleteTagsHandler = async (request) => {
const { event } = request.body;
if (!event.tags || !event.id) throw new Error(CommonErrorsEnum.NO_PAYLOAD_PROVIDED);
const token = request.headers.authorization;
if (!token) throw new Error(CommonErrorsEnum.UNAUTHORIZED);

const jwtData = jwt.verify(token, vars.secret) as ITokenData;
if (!jwtData.id) throw new Error(CommonErrorsEnum.WRONG_TOKEN);

event.creatorId = jwtData.id;
const response = await eventsStateController.removeTags(event);

return response;
};
// export const deleteTag: IDeleteTagsHandler = async (request) => {
// const { event } = request.body;
// if (!event.tags || !event.id) throw new Error(CommonErrorsEnum.NO_PAYLOAD_PROVIDED);
// const token = request.headers.authorization;
// if (!token) throw new Error(CommonErrorsEnum.UNAUTHORIZED);
//
// const jwtData = jwt.verify(token, vars.secret) as ITokenData;
// if (!jwtData.id) throw new Error(CommonErrorsEnum.WRONG_TOKEN);
//
// event.creatorId = jwtData.id;
// const response = await eventsStateController.removeTags(event);
//
// return response;
// };
Loading

0 comments on commit a0cbe75

Please sign in to comment.