Browse Source

fix: address review comments - upload path, validation, env credentials, entrypoint, i18n

Co-authored-by: RobertgPatch <5817970+RobertgPatch@users.noreply.github.com>
pull/6603/head^2
copilot-swe-agent[bot] 2 weeks ago
parent
commit
2f2ebd1f39
  1. 10
      .env.dev
  2. 21
      apps/api/src/app/family-office/family-office.controller.ts
  3. 9
      apps/api/src/app/upload/upload.controller.ts
  4. 6
      apps/api/src/app/upload/upload.module.ts
  5. 2
      apps/api/src/app/upload/upload.service.ts
  6. 7
      apps/client/src/app/pages/partnership-detail/record-valuation-dialog/record-valuation-dialog.component.ts
  7. 2
      apps/client/src/app/pages/partnerships/partnerships-page.routes.ts
  8. 6
      docker/entrypoint.sh

10
.env.dev

@ -3,18 +3,18 @@ COMPOSE_PROJECT_NAME=ghostfolio-development
# CACHE
REDIS_HOST=localhost
REDIS_PORT=6379
REDIS_PASSWORD=b126659952eb48d08cc9fc9d966903ff
REDIS_PASSWORD=<INSERT_REDIS_PASSWORD>
# POSTGRES
POSTGRES_DB=ghostfolio-db
POSTGRES_USER=user
POSTGRES_PASSWORD=302653e0a3b94dd2942bc283f269fc62
POSTGRES_PASSWORD=<INSERT_POSTGRES_PASSWORD>
POSTGRES_PORT=5434
# VARIOUS
ACCESS_TOKEN_SALT=34f2558b9a934517a978d69ab501fcfd
DATABASE_URL=postgresql://user:302653e0a3b94dd2942bc283f269fc62@localhost:5434/ghostfolio-db?connect_timeout=300&sslmode=prefer
JWT_SECRET_KEY=12005231ada14bd1919967473625bec4
ACCESS_TOKEN_SALT=<INSERT_RANDOM_STRING>
DATABASE_URL=postgresql://user:<INSERT_POSTGRES_PASSWORD>@localhost:5434/ghostfolio-db?connect_timeout=300&sslmode=prefer
JWT_SECRET_KEY=<INSERT_RANDOM_STRING>
# DEVELOPMENT
HOST=0.0.0.0

21
apps/api/src/app/family-office/family-office.controller.ts

@ -3,7 +3,14 @@ import { HasPermissionGuard } from '@ghostfolio/api/guards/has-permission.guard'
import { permissions } from '@ghostfolio/common/permissions';
import type { RequestWithUser } from '@ghostfolio/common/types';
import { Controller, Get, Inject, Query, UseGuards } from '@nestjs/common';
import {
BadRequestException,
Controller,
Get,
Inject,
Query,
UseGuards
} from '@nestjs/common';
import { REQUEST } from '@nestjs/core';
import { AuthGuard } from '@nestjs/passport';
@ -92,17 +99,17 @@ export class FamilyOfficeController {
@Query('year') year?: string
) {
if (!period || !year) {
return {
error: 'period and year are required query parameters'
};
throw new BadRequestException(
'period and year are required query parameters'
);
}
const validPeriods = ['MONTHLY', 'QUARTERLY', 'YEARLY'];
if (!validPeriods.includes(period)) {
return {
error: `period must be one of: ${validPeriods.join(', ')}`
};
throw new BadRequestException(
`period must be one of: ${validPeriods.join(', ')}`
);
}
const yearNum = parseInt(year, 10);

9
apps/api/src/app/upload/upload.controller.ts

@ -4,6 +4,7 @@ import { permissions } from '@ghostfolio/common/permissions';
import type { RequestWithUser } from '@ghostfolio/common/types';
import {
BadRequestException,
Controller,
Get,
Inject,
@ -36,6 +37,14 @@ export class UploadController {
public async uploadDocument(@UploadedFile() file: any) {
const body = this.request.body as any;
const validDocumentTypes = Object.values(DocumentType);
if (!body.type || !validDocumentTypes.includes(body.type as DocumentType)) {
throw new BadRequestException(
`type must be one of: ${validDocumentTypes.join(', ')}`
);
}
return this.uploadService.createDocument({
file,
entityId: body.entityId,

6
apps/api/src/app/upload/upload.module.ts

@ -4,7 +4,7 @@ import { Module } from '@nestjs/common';
import { MulterModule } from '@nestjs/platform-express';
import { diskStorage } from 'multer';
import { existsSync, mkdirSync } from 'node:fs';
import { join } from 'node:path';
import { extname, join } from 'node:path';
import { v4 as uuidv4 } from 'uuid';
import { UploadController } from './upload.controller';
@ -38,8 +38,8 @@ if (!existsSync(uploadDir)) {
cb(null, subDir);
},
filename: (_req, file, cb) => {
const ext = file.originalname.split('.').pop();
cb(null, `${uuidv4()}.${ext}`);
const ext = extname(file.originalname);
cb(null, ext ? `${uuidv4()}${ext}` : uuidv4());
}
})
}),

2
apps/api/src/app/upload/upload.service.ts

@ -51,7 +51,7 @@ export class UploadService {
await mkdir(subDir, { recursive: true });
}
const relativePath = `/${yearDir}/${monthDir}/${file.filename}`;
const relativePath = `${yearDir}/${monthDir}/${file.filename}`;
return this.prismaService.document.create({
data: {

7
apps/client/src/app/pages/partnership-detail/record-valuation-dialog/record-valuation-dialog.component.ts

@ -62,10 +62,11 @@ import { MatSelectModule } from '@angular/material/select';
<mat-form-field appearance="outline" class="w-100">
<mat-label i18n>Source</mat-label>
<mat-select formControlName="source" required>
<mat-option value="STATEMENT">Statement</mat-option>
<mat-option value="NAV_STATEMENT">Statement</mat-option>
<mat-option value="MANUAL">Manual Entry</mat-option>
<mat-option value="AUDITOR">Auditor</mat-option>
<mat-option value="APPRAISAL">Appraisal</mat-option>
<mat-option value="FUND_ADMIN">Fund Admin</mat-option>
<mat-option value="MARKET">Market</mat-option>
</mat-select>
</mat-form-field>
</div>
@ -108,7 +109,7 @@ export class GfRecordValuationDialogComponent implements OnInit {
Validators.required
]),
nav: new FormControl(null, [Validators.required, Validators.min(0)]),
source: new FormControl('STATEMENT', [Validators.required]),
source: new FormControl('NAV_STATEMENT', [Validators.required]),
notes: new FormControl('')
});
}

2
apps/client/src/app/pages/partnerships/partnerships-page.routes.ts

@ -9,6 +9,6 @@ export const routes: Routes = [
canActivate: [AuthGuard],
component: GfPartnershipsPageComponent,
path: '',
title: 'Partnerships'
title: $localize`Partnerships`
}
];

6
docker/entrypoint.sh

@ -5,8 +5,10 @@ set -e
echo "==> Running database migrations"
npx prisma migrate deploy
echo "==> Ensuring schema is fully synced"
npx prisma db push --skip-generate --accept-data-loss 2>/dev/null || echo " (db push skipped — schema already in sync)"
if [ "${DB_PUSH_ON_STARTUP}" = "true" ]; then
echo "==> Syncing schema (DB_PUSH_ON_STARTUP=true)"
npx prisma db push --skip-generate --accept-data-loss || echo " (db push failed -- check schema and database state)"
fi
echo "==> Seeding the database (if applicable)"
npx prisma db seed || echo " (seed skipped or already applied)"

Loading…
Cancel
Save