-
-
Notifications
You must be signed in to change notification settings - Fork 3.6k
Add automation for software engineering process #541
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,13 +20,15 @@ import { getCookieUrlFromDomain } from '@gitroom/helpers/subdomain/subdomain.man | |
import { EmailService } from '@gitroom/nestjs-libraries/services/email.service'; | ||
import { RealIP } from 'nestjs-real-ip'; | ||
import { UserAgent } from '@gitroom/nestjs-libraries/user/user.agent'; | ||
import { ProjectManagementService } from '@gitroom/backend/services/project-management/project-management.service'; | ||
|
||
@ApiTags('Auth') | ||
@Controller('/auth') | ||
export class AuthController { | ||
constructor( | ||
private _authService: AuthService, | ||
private _emailService: EmailService | ||
private _emailService: EmailService, | ||
private _projectManagementService: ProjectManagementService | ||
) {} | ||
@Post('/register') | ||
async register( | ||
|
@@ -207,4 +209,84 @@ export class AuthController { | |
login: true, | ||
}); | ||
} | ||
|
||
@Post('/project-management/create-roadmap') | ||
async createRoadmap( | ||
@Body() body: { title: string; description: string }, | ||
@Res() response: Response | ||
) { | ||
try { | ||
const roadmap = await this._projectManagementService.createRoadmap( | ||
body.title, | ||
body.description | ||
); | ||
response.status(201).json(roadmap); | ||
} catch (e) { | ||
response.status(400).send(e.message); | ||
} | ||
} | ||
|
||
@Post('/project-management/create-user-story') | ||
async createUserStory( | ||
@Body() body: { roadmapId: string; title: string; description: string }, | ||
@Res() response: Response | ||
) { | ||
try { | ||
const userStory = await this._projectManagementService.createUserStory( | ||
body.roadmapId, | ||
body.title, | ||
body.description | ||
); | ||
response.status(201).json(userStory); | ||
} catch (e) { | ||
response.status(400).send(e.message); | ||
} | ||
} | ||
|
||
@Post('/project-management/create-task') | ||
async createTask( | ||
@Body() body: { userStoryId: string; title: string; description: string }, | ||
@Res() response: Response | ||
) { | ||
try { | ||
const task = await this._projectManagementService.createTask( | ||
body.userStoryId, | ||
body.title, | ||
body.description | ||
); | ||
response.status(201).json(task); | ||
} catch (e) { | ||
response.status(400).send(e.message); | ||
} | ||
} | ||
|
||
@Get('/project-management/track-progress') | ||
async trackProgress(@Res() response: Response) { | ||
try { | ||
const progress = await this._projectManagementService.trackProgress(); | ||
response.status(200).json(progress); | ||
} catch (e) { | ||
response.status(400).send(e.message); | ||
} | ||
} | ||
|
||
@Get('/project-management/estimate-timelines') | ||
async estimateTimelines(@Res() response: Response) { | ||
try { | ||
const timelines = await this._projectManagementService.estimateTimelines(); | ||
response.status(200).json(timelines); | ||
} catch (e) { | ||
response.status(400).send(e.message); | ||
} | ||
} | ||
|
||
@Get('/project-management/identify-roadblocks') | ||
async identifyRoadblocks(@Res() response: Response) { | ||
try { | ||
const roadblocks = await this._projectManagementService.identifyRoadblocks(); | ||
response.status(200).json(roadblocks); | ||
} catch (e) { | ||
response.status(400).send(e.message); | ||
} | ||
} | ||
Comment on lines
+213
to
+291
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Missing authentication and authorization on project management endpoints The newly added project management endpoints ( Consider using guards or decorators to enforce authentication: @UseGuards(AuthGuard('jwt'))
@Post('/project-management/create-roadmap')
async createRoadmap(/* ... */) { /* ... */ } |
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
import { Logger, Controller, Get, Post, Req, Res } from '@nestjs/common'; | ||
import { Logger, Controller, Get, Post, Req, Res, Body } from '@nestjs/common'; | ||
import { | ||
CopilotRuntime, | ||
OpenAIAdapter, | ||
|
@@ -7,10 +7,17 @@ import { | |
import { GetOrgFromRequest } from '@gitroom/nestjs-libraries/user/org.from.request'; | ||
import { Organization } from '@prisma/client'; | ||
import { SubscriptionService } from '@gitroom/nestjs-libraries/database/prisma/subscriptions/subscription.service'; | ||
import { CommunicationService } from '@gitroom/backend/services/communication/communication.service'; | ||
import { DocumentationService } from '@gitroom/backend/services/documentation/documentation.service'; | ||
|
||
@Controller('/copilot') | ||
export class CopilotController { | ||
constructor(private _subscriptionService: SubscriptionService) {} | ||
constructor( | ||
private _subscriptionService: SubscriptionService, | ||
private _communicationService: CommunicationService, | ||
private _documentationService: DocumentationService | ||
) {} | ||
|
||
@Post('/chat') | ||
chat(@Req() req: Request, @Res() res: Response) { | ||
if (process.env.OPENAI_API_KEY === undefined || process.env.OPENAI_API_KEY === '') { | ||
|
@@ -39,4 +46,61 @@ export class CopilotController { | |
calculateCredits(@GetOrgFromRequest() organization: Organization) { | ||
return this._subscriptionService.checkCredits(organization); | ||
} | ||
|
||
@Post('/communicate') | ||
async facilitateCommunication( | ||
@Body() body: { message: string; recipients: string[] }, | ||
@Res() response: Response | ||
) { | ||
try { | ||
const result = await this._communicationService.sendMessage( | ||
body.message, | ||
body.recipients | ||
); | ||
response.status(200).json(result); | ||
} catch (e) { | ||
response.status(400).send(e.message); | ||
} | ||
} | ||
|
||
@Post('/generate-documentation') | ||
async generateDocumentation( | ||
@Body() body: { projectId: string }, | ||
@Res() response: Response | ||
) { | ||
try { | ||
const documentation = await this._documentationService.generateDocumentation( | ||
body.projectId | ||
); | ||
response.status(200).json(documentation); | ||
} catch (e) { | ||
response.status(400).send(e.message); | ||
} | ||
} | ||
|
||
@Post('/integrate-slack') | ||
async integrateSlack( | ||
@Body() body: { slackToken: string }, | ||
@Res() response: Response | ||
) { | ||
try { | ||
const result = await this._communicationService.integrateSlack(body.slackToken); | ||
response.status(200).json(result); | ||
} catch (e) { | ||
response.status(400).send(e.message); | ||
} | ||
} | ||
|
||
@Post('/integrate-teams') | ||
async integrateTeams( | ||
@Body() body: { teamsToken: string }, | ||
@Res() response: Response | ||
) { | ||
try { | ||
const result = await this._communicationService.integrateTeams(body.teamsToken); | ||
response.status(200).json(result); | ||
} catch (e) { | ||
response.status(400).send(e.message); | ||
} | ||
} | ||
Comment on lines
+81
to
+105
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Security concern: Avoid passing tokens directly in request bodies Passing sensitive tokens like |
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -44,7 +44,7 @@ export class IntegrationsController { | |
private _integrationManager: IntegrationManager, | ||
private _integrationService: IntegrationService, | ||
private _postService: PostsService | ||
) {} | ||
) { } | ||
@Get('/') | ||
getIntegration() { | ||
return this._integrationManager.getAllIntegrations(); | ||
|
@@ -147,18 +147,18 @@ export class IntegrationsController { | |
|
||
const { url } = manager.changeProfilePicture | ||
? await manager.changeProfilePicture( | ||
integration.internalId, | ||
integration.token, | ||
body.picture | ||
) | ||
integration.internalId, | ||
integration.token, | ||
body.picture | ||
) | ||
: { url: '' }; | ||
|
||
const { name } = manager.changeNickname | ||
? await manager.changeNickname( | ||
integration.internalId, | ||
integration.token, | ||
body.name | ||
) | ||
integration.internalId, | ||
integration.token, | ||
body.name | ||
) | ||
: { name: '' }; | ||
|
||
return this._integrationService.updateNameAndUrl(id, name, url); | ||
|
@@ -204,9 +204,9 @@ export class IntegrationsController { | |
try { | ||
const getExternalUrl = integrationProvider.externalUrl | ||
? { | ||
...(await integrationProvider.externalUrl(externalUrl)), | ||
instanceUrl: externalUrl, | ||
} | ||
...(await integrationProvider.externalUrl(externalUrl)), | ||
instanceUrl: externalUrl, | ||
} | ||
: undefined; | ||
|
||
const { codeVerifier, state, url } = | ||
|
@@ -506,10 +506,10 @@ export class IntegrationsController { | |
details | ||
? AuthService.fixedEncryption(details) | ||
: integrationProvider.customFields | ||
? AuthService.fixedEncryption( | ||
? AuthService.fixedEncryption( | ||
Buffer.from(body.code, 'base64').toString() | ||
) | ||
: undefined | ||
: undefined | ||
); | ||
} | ||
|
||
|
@@ -609,4 +609,28 @@ export class IntegrationsController { | |
) { | ||
return this._integrationService.changePlugActivation(org.id, id, status); | ||
} | ||
|
||
@Post('/deploy') | ||
async deployToEnvironment( | ||
@GetOrgFromRequest() org: Organization, | ||
@Body() body: { environment: string } | ||
) { | ||
// Add logic to automate deployment to various environments | ||
return this._integrationService.deployToEnvironment(org.id, body.environment); | ||
} | ||
Comment on lines
+613
to
+620
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 Codebase verification Review comment is valid and critical The deployment endpoint lacks essential security measures and implementation:
The original review comment correctly identifies critical security concerns that need to be addressed before this endpoint can be safely used. 🔗 Analysis chainAdd input validation and error handling for deployment endpoint The deployment endpoint needs additional security measures:
🏁 Scripts executedThe following scripts were executed for the analysis: Script: #!/bin/bash
# Check if deployment-related permissions are implemented
ast-grep --pattern 'class $_ implements $_ {
$$$
@CheckPolicies([AuthorizationActions.$_, Sections.$_])
$$$
deployToEnvironment($$$) {
$$$
}
$$$
}'
Length of output: 165 Script: #!/bin/bash
# Check for any decorators in integrations controller
echo "=== Checking decorators ==="
ast-grep --pattern '@$_($$$)
$$$' apps/backend/src/api/routes/integrations.controller.ts
# Look for environment validation
echo "=== Checking environment validation ==="
rg -A 5 "environment.*validation|validateEnvironment" apps/backend/src/api
# Check integration service implementation
echo "=== Checking integration service ==="
fd "integration.service" --type f --exec cat {}
Length of output: 17975 Script: #!/bin/bash
# Search for environment-related types or enums
echo "=== Checking environment types ==="
rg -g "*.ts" "enum.*Environment|type.*Environment|interface.*Environment"
# Search for environment constants
echo "=== Checking environment constants ==="
rg -g "*.ts" "const.*Environment.*=|export.*Environment.*="
# Check for any existing deployment-related code
echo "=== Checking deployment patterns ==="
rg -g "*.ts" "deploy.*environment|environment.*deploy" -A 3
Length of output: 906 |
||
|
||
@Get('/monitor-performance') | ||
async monitorSystemPerformance(@GetOrgFromRequest() org: Organization) { | ||
// Add logic to monitor system performance and identify potential issues | ||
return this._integrationService.monitorSystemPerformance(org.id); | ||
} | ||
Comment on lines
+622
to
+626
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Implement rate limiting for performance monitoring endpoint The performance monitoring endpoint should:
@Get('/monitor-performance')
+ @UseInterceptors(RateLimitInterceptor)
async monitorSystemPerformance(@GetOrgFromRequest() org: Organization) {
- // Add logic to monitor system performance and identify potential issues
- return this._integrationService.monitorSystemPerformance(org.id);
+ const cacheKey = `performance:${org.id}`;
+ const cached = await this.cacheManager.get(cacheKey);
+ if (cached) return cached;
+
+ const metrics = await this._integrationService.monitorSystemPerformance(org.id);
+ await this.cacheManager.set(cacheKey, metrics, 300);
+ return metrics;
}
|
||
|
||
@Post('/bug-fix') | ||
async automateBugFixes( | ||
@GetOrgFromRequest() org: Organization, | ||
@Body() body: { feedback: string } | ||
) { | ||
// Add logic to automate bug fixes and updates based on user feedback and system logs | ||
return this._integrationService.automateBugFixes(org.id, body.feedback); | ||
} | ||
Comment on lines
+628
to
+635
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add validation and sanitization for bug fix automation endpoint The bug fix automation endpoint needs:
@Post('/bug-fix')
+ @UseInterceptors(RateLimitInterceptor)
async automateBugFixes(
@GetOrgFromRequest() org: Organization,
- @Body() body: { feedback: string }
+ @Body() body: AutomateBugFixDto
) {
- // Add logic to automate bug fixes and updates based on user feedback and system logs
+ this.logger.info(`Automating bug fix for org ${org.id} with feedback: ${body.feedback}`);
+ try {
+ return await this._integrationService.automateBugFixes(org.id, body.feedback);
+ } catch (error) {
+ this.logger.error(`Bug fix automation failed: ${error.message}`);
+ throw new InternalServerErrorException('Failed to automate bug fix');
+ }
}
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -27,6 +27,9 @@ import { CreateGeneratedPostsDto } from '@gitroom/nestjs-libraries/dtos/generato | |
import { AgentGraphService } from '@gitroom/nestjs-libraries/agent/agent.graph.service'; | ||
import { Response } from 'express'; | ||
import { GetUserFromRequest } from '@gitroom/nestjs-libraries/user/user.from.request'; | ||
import { CodeGenerationService } from '@gitroom/backend/services/code-generation/code-generation.service'; | ||
import { TestingService } from '@gitroom/backend/services/testing/testing.service'; | ||
import { CICDService } from '@gitroom/backend/services/cicd/cicd.service'; | ||
|
||
@ApiTags('Posts') | ||
@Controller('/posts') | ||
|
@@ -35,7 +38,10 @@ export class PostsController { | |
private _postsService: PostsService, | ||
private _starsService: StarsService, | ||
private _messagesService: MessagesService, | ||
private _agentGraphService: AgentGraphService | ||
private _agentGraphService: AgentGraphService, | ||
private _codeGenerationService: CodeGenerationService, | ||
private _testingService: TestingService, | ||
private _cicdService: CICDService | ||
) {} | ||
|
||
@Get('/marketplace/:id?') | ||
|
@@ -138,6 +144,34 @@ export class PostsController { | |
res.end(); | ||
} | ||
|
||
@Post('/code-generation') | ||
async generateCode( | ||
@GetOrgFromRequest() org: Organization, | ||
@Body() body: { userStoryId: string } | ||
) { | ||
return this._codeGenerationService.generateCode(org.id, body.userStoryId); | ||
} | ||
|
||
@Post('/testing/unit') | ||
async runUnitTests(@GetOrgFromRequest() org: Organization) { | ||
return this._testingService.runUnitTests(org.id); | ||
} | ||
|
||
@Post('/testing/integration') | ||
async runIntegrationTests(@GetOrgFromRequest() org: Organization) { | ||
return this._testingService.runIntegrationTests(org.id); | ||
} | ||
|
||
@Post('/testing/e2e') | ||
async runE2ETests(@GetOrgFromRequest() org: Organization) { | ||
return this._testingService.runE2ETests(org.id); | ||
} | ||
|
||
@Post('/cicd/pipeline') | ||
async triggerCICDPipeline(@GetOrgFromRequest() org: Organization) { | ||
return this._cicdService.triggerPipeline(org.id); | ||
} | ||
Comment on lines
+147
to
+173
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add error handling to new methods The methods Example: @Post('/code-generation')
async generateCode(
@GetOrgFromRequest() org: Organization,
@Body() body: { userStoryId: string }
) {
try {
return await this._codeGenerationService.generateCode(org.id, body.userStoryId);
} catch (e) {
throw new BadRequestException(e.message);
}
} Ensure you import the necessary exceptions from |
||
|
||
@Delete('/:group') | ||
deletePost( | ||
@GetOrgFromRequest() org: Organization, | ||
|
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -48,6 +48,41 @@ services: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
networks: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
- postiz-network | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
restart: always | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
postiz-backend: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
build: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
context: . | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
dockerfile: Dockerfile.dev | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
target: devcontainer | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
container_name: postiz-backend | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
restart: always | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
environment: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
DATABASE_URL: "postgresql://postiz-local:postiz-local-pwd@postiz-postgres:5432/postiz-db-local" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
REDIS_URL: "redis://postiz-redis:6379" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
JWT_SECRET: "random string for your JWT secret, make it long" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
FRONTEND_URL: "http://localhost:4200" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
NEXT_PUBLIC_BACKEND_URL: "http://localhost:3000" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
BACKEND_INTERNAL_URL: "http://localhost:3000" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
volumes: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
- ./apps/backend:/app | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
ports: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
- 3000:3000 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
networks: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
- postiz-network | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+51
to
+70
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Enhance backend service configuration security and reliability The backend service configuration needs improvements:
postiz-backend:
build:
context: .
dockerfile: Dockerfile.dev
target: devcontainer
container_name: postiz-backend
restart: always
+ healthcheck:
+ test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
+ interval: 30s
+ timeout: 10s
+ retries: 3
+ deploy:
+ resources:
+ limits:
+ cpus: '1'
+ memory: 1G
environment:
DATABASE_URL: "postgresql://postiz-local:postiz-local-pwd@postiz-postgres:5432/postiz-db-local"
REDIS_URL: "redis://postiz-redis:6379"
- JWT_SECRET: "random string for your JWT secret, make it long"
+ JWT_SECRET: ${JWT_SECRET}
FRONTEND_URL: "http://localhost:4200"
NEXT_PUBLIC_BACKEND_URL: "http://localhost:3000"
BACKEND_INTERNAL_URL: "http://localhost:3000" 📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
postiz-frontend: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
build: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
context: . | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
dockerfile: Dockerfile.dev | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
target: devcontainer | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
container_name: postiz-frontend | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
restart: always | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
environment: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
NEXT_PUBLIC_BACKEND_URL: "http://localhost:3000" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
volumes: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
- ./apps/frontend:/app | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
ports: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
- 4200:4200 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
networks: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
- postiz-network | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+71
to
+85
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Add health check and resource limits to frontend service The frontend service configuration needs similar improvements:
postiz-frontend:
build:
context: .
dockerfile: Dockerfile.dev
target: devcontainer
container_name: postiz-frontend
restart: always
+ healthcheck:
+ test: ["CMD", "curl", "-f", "http://localhost:4200"]
+ interval: 30s
+ timeout: 10s
+ retries: 3
+ deploy:
+ resources:
+ limits:
+ cpus: '0.5'
+ memory: 512M
environment:
NEXT_PUBLIC_BACKEND_URL: "http://localhost:3000" 📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
volumes: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
redisinsight: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,14 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
#!/bin/bash | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# Install necessary dependencies and tools | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
echo "Installing necessary dependencies and tools..." | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
npm install -g @nestjs/cli | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
npm install | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# Set up environment variables and configuration files | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
echo "Setting up environment variables and configuration files..." | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
cp .env.example .env | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# Launch the project using Docker Compose | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
echo "Launching the project using Docker Compose..." | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
docker-compose -f docker-compose.dev.yaml up --build | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+1
to
+14
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Add error handling and prerequisite checks The setup script needs improvements for reliability:
#!/bin/bash
+set -euo pipefail
+
+# Function to check prerequisites
+check_prerequisites() {
+ command -v docker >/dev/null 2>&1 || { echo "Docker is required but not installed. Aborting." >&2; exit 1; }
+ command -v npm >/dev/null 2>&1 || { echo "npm is required but not installed. Aborting." >&2; exit 1; }
+}
+
+# Function to clean up on failure
+cleanup() {
+ echo "Setup failed. Cleaning up..."
+ docker-compose -f docker-compose.dev.yaml down
+ exit 1
+}
+
+# Set up error handling
+trap cleanup ERR
+
+# Check prerequisites
+check_prerequisites
# Install necessary dependencies and tools
echo "Installing necessary dependencies and tools..."
npm install -g @nestjs/cli
-npm install
+npm install || { echo "Failed to install dependencies. Aborting." >&2; exit 1; }
# Set up environment variables and configuration files
echo "Setting up environment variables and configuration files..."
-cp .env.example .env
+if [ ! -f .env.example ]; then
+ echo ".env.example not found. Aborting." >&2
+ exit 1
+fi
+cp .env.example .env || { echo "Failed to create .env file. Aborting." >&2; exit 1; }
# Launch the project using Docker Compose
echo "Launching the project using Docker Compose..."
-docker-compose -f docker-compose.dev.yaml up --build
+docker-compose -f docker-compose.dev.yaml up --build || cleanup 📝 Committable suggestion
Suggested change
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Add input validation to project management methods
The methods accepting input (
createRoadmap
,createUserStory
,createTask
) should validate the incoming data to prevent invalid or malicious input.Define DTOs with validation decorators:
Update your method to use the DTO: