feat: version check endpoint (#18572)

This commit is contained in:
Daniel Dietzler 2025-05-27 16:33:23 +02:00 committed by GitHub
parent ef060e97b6
commit 5268dc4ee2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 135 additions and 1 deletions

BIN
mobile/openapi/README.md generated

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -5563,6 +5563,38 @@
] ]
} }
}, },
"/server/version-check": {
"get": {
"operationId": "getVersionCheck",
"parameters": [],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/VersionCheckStateResponseDto"
}
}
},
"description": ""
}
},
"security": [
{
"bearer": []
},
{
"cookie": []
},
{
"api_key": []
}
],
"tags": [
"Server"
]
}
},
"/server/version-history": { "/server/version-history": {
"get": { "get": {
"operationId": "getVersionHistory", "operationId": "getVersionHistory",
@ -6846,6 +6878,38 @@
] ]
} }
}, },
"/system-metadata/version-check-state": {
"get": {
"operationId": "getVersionCheckState",
"parameters": [],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/VersionCheckStateResponseDto"
}
}
},
"description": ""
}
},
"security": [
{
"bearer": []
},
{
"cookie": []
},
{
"api_key": []
}
],
"tags": [
"System Metadata"
]
}
},
"/tags": { "/tags": {
"get": { "get": {
"operationId": "getAllTags", "operationId": "getAllTags",
@ -14939,6 +15003,23 @@
}, },
"type": "object" "type": "object"
}, },
"VersionCheckStateResponseDto": {
"properties": {
"checkedAt": {
"nullable": true,
"type": "string"
},
"releaseVersion": {
"nullable": true,
"type": "string"
}
},
"required": [
"checkedAt",
"releaseVersion"
],
"type": "object"
},
"VideoCodec": { "VideoCodec": {
"enum": [ "enum": [
"h264", "h264",

View file

@ -1076,6 +1076,10 @@ export type ServerVersionResponseDto = {
minor: number; minor: number;
patch: number; patch: number;
}; };
export type VersionCheckStateResponseDto = {
checkedAt: string | null;
releaseVersion: string | null;
};
export type ServerVersionHistoryResponseDto = { export type ServerVersionHistoryResponseDto = {
createdAt: string; createdAt: string;
id: string; id: string;
@ -2947,6 +2951,14 @@ export function getServerVersion(opts?: Oazapfts.RequestOpts) {
...opts ...opts
})); }));
} }
export function getVersionCheck(opts?: Oazapfts.RequestOpts) {
return oazapfts.ok(oazapfts.fetchJson<{
status: 200;
data: VersionCheckStateResponseDto;
}>("/server/version-check", {
...opts
}));
}
export function getVersionHistory(opts?: Oazapfts.RequestOpts) { export function getVersionHistory(opts?: Oazapfts.RequestOpts) {
return oazapfts.ok(oazapfts.fetchJson<{ return oazapfts.ok(oazapfts.fetchJson<{
status: 200; status: 200;
@ -3284,6 +3296,14 @@ export function getReverseGeocodingState(opts?: Oazapfts.RequestOpts) {
...opts ...opts
})); }));
} }
export function getVersionCheckState(opts?: Oazapfts.RequestOpts) {
return oazapfts.ok(oazapfts.fetchJson<{
status: 200;
data: VersionCheckStateResponseDto;
}>("/system-metadata/version-check-state", {
...opts
}));
}
export function getAllTags(opts?: Oazapfts.RequestOpts) { export function getAllTags(opts?: Oazapfts.RequestOpts) {
return oazapfts.ok(oazapfts.fetchJson<{ return oazapfts.ok(oazapfts.fetchJson<{
status: 200; status: 200;

View file

@ -1,5 +1,6 @@
import { ServerController } from 'src/controllers/server.controller'; import { ServerController } from 'src/controllers/server.controller';
import { ServerService } from 'src/services/server.service'; import { ServerService } from 'src/services/server.service';
import { SystemMetadataService } from 'src/services/system-metadata.service';
import { VersionService } from 'src/services/version.service'; import { VersionService } from 'src/services/version.service';
import request from 'supertest'; import request from 'supertest';
import { ControllerContext, controllerSetup, mockBaseService } from 'test/utils'; import { ControllerContext, controllerSetup, mockBaseService } from 'test/utils';
@ -7,11 +8,13 @@ import { ControllerContext, controllerSetup, mockBaseService } from 'test/utils'
describe(ServerController.name, () => { describe(ServerController.name, () => {
let ctx: ControllerContext; let ctx: ControllerContext;
const serverService = mockBaseService(ServerService); const serverService = mockBaseService(ServerService);
const systemMetadataService = mockBaseService(SystemMetadataService);
const versionService = mockBaseService(VersionService); const versionService = mockBaseService(VersionService);
beforeAll(async () => { beforeAll(async () => {
ctx = await controllerSetup(ServerController, [ ctx = await controllerSetup(ServerController, [
{ provide: ServerService, useValue: serverService }, { provide: ServerService, useValue: serverService },
{ provide: SystemMetadataService, useValue: systemMetadataService },
{ provide: VersionService, useValue: versionService }, { provide: VersionService, useValue: versionService },
]); ]);
return () => ctx.close(); return () => ctx.close();

View file

@ -13,8 +13,10 @@ import {
ServerVersionHistoryResponseDto, ServerVersionHistoryResponseDto,
ServerVersionResponseDto, ServerVersionResponseDto,
} from 'src/dtos/server.dto'; } from 'src/dtos/server.dto';
import { VersionCheckStateResponseDto } from 'src/dtos/system-metadata.dto';
import { Authenticated } from 'src/middleware/auth.guard'; import { Authenticated } from 'src/middleware/auth.guard';
import { ServerService } from 'src/services/server.service'; import { ServerService } from 'src/services/server.service';
import { SystemMetadataService } from 'src/services/system-metadata.service';
import { VersionService } from 'src/services/version.service'; import { VersionService } from 'src/services/version.service';
@ApiTags('Server') @ApiTags('Server')
@ -22,6 +24,7 @@ import { VersionService } from 'src/services/version.service';
export class ServerController { export class ServerController {
constructor( constructor(
private service: ServerService, private service: ServerService,
private systemMetadataService: SystemMetadataService,
private versionService: VersionService, private versionService: VersionService,
) {} ) {}
@ -96,4 +99,10 @@ export class ServerController {
getServerLicense(): Promise<LicenseResponseDto> { getServerLicense(): Promise<LicenseResponseDto> {
return this.service.getLicense(); return this.service.getLicense();
} }
@Get('version-check')
@Authenticated()
getVersionCheck(): Promise<VersionCheckStateResponseDto> {
return this.systemMetadataService.getVersionCheckState();
}
} }

View file

@ -1,6 +1,10 @@
import { Body, Controller, Get, HttpCode, HttpStatus, Post } from '@nestjs/common'; import { Body, Controller, Get, HttpCode, HttpStatus, Post } from '@nestjs/common';
import { ApiTags } from '@nestjs/swagger'; import { ApiTags } from '@nestjs/swagger';
import { AdminOnboardingUpdateDto, ReverseGeocodingStateResponseDto } from 'src/dtos/system-metadata.dto'; import {
AdminOnboardingUpdateDto,
ReverseGeocodingStateResponseDto,
VersionCheckStateResponseDto,
} from 'src/dtos/system-metadata.dto';
import { Permission } from 'src/enum'; import { Permission } from 'src/enum';
import { Authenticated } from 'src/middleware/auth.guard'; import { Authenticated } from 'src/middleware/auth.guard';
import { SystemMetadataService } from 'src/services/system-metadata.service'; import { SystemMetadataService } from 'src/services/system-metadata.service';
@ -28,4 +32,10 @@ export class SystemMetadataController {
getReverseGeocodingState(): Promise<ReverseGeocodingStateResponseDto> { getReverseGeocodingState(): Promise<ReverseGeocodingStateResponseDto> {
return this.service.getReverseGeocodingState(); return this.service.getReverseGeocodingState();
} }
@Get('version-check-state')
@Authenticated({ permission: Permission.SYSTEM_METADATA_READ, admin: true })
getVersionCheckState(): Promise<VersionCheckStateResponseDto> {
return this.service.getVersionCheckState();
}
} }

View file

@ -13,3 +13,8 @@ export class ReverseGeocodingStateResponseDto {
lastUpdate!: string | null; lastUpdate!: string | null;
lastImportFileName!: string | null; lastImportFileName!: string | null;
} }
export class VersionCheckStateResponseDto {
checkedAt!: string | null;
releaseVersion!: string | null;
}

View file

@ -3,6 +3,7 @@ import {
AdminOnboardingResponseDto, AdminOnboardingResponseDto,
AdminOnboardingUpdateDto, AdminOnboardingUpdateDto,
ReverseGeocodingStateResponseDto, ReverseGeocodingStateResponseDto,
VersionCheckStateResponseDto,
} from 'src/dtos/system-metadata.dto'; } from 'src/dtos/system-metadata.dto';
import { SystemMetadataKey } from 'src/enum'; import { SystemMetadataKey } from 'src/enum';
import { BaseService } from 'src/services/base.service'; import { BaseService } from 'src/services/base.service';
@ -24,4 +25,9 @@ export class SystemMetadataService extends BaseService {
const value = await this.systemMetadataRepository.get(SystemMetadataKey.REVERSE_GEOCODING_STATE); const value = await this.systemMetadataRepository.get(SystemMetadataKey.REVERSE_GEOCODING_STATE);
return { lastUpdate: null, lastImportFileName: null, ...value }; return { lastUpdate: null, lastImportFileName: null, ...value };
} }
async getVersionCheckState(): Promise<VersionCheckStateResponseDto> {
const value = await this.systemMetadataRepository.get(SystemMetadataKey.VERSION_CHECK_STATE);
return { checkedAt: null, releaseVersion: null, ...value };
}
} }