fix: passtrough into pak vegacloud internal routing

This commit is contained in:
2025-12-08 19:32:32 +07:00
parent e81c6bdddc
commit 3dee9b7a4d
5 changed files with 63 additions and 38 deletions
-1
View File
@@ -94,7 +94,6 @@ export const apiKeyAuthMacro = new Elysia().macro({
if (!enabled) { if (!enabled) {
return return
} }
const apiKey = headers['x-api-key'] const apiKey = headers['x-api-key']
const nonce = headers['x-nonce'] const nonce = headers['x-nonce']
const signature = headers['x-signature'] const signature = headers['x-signature']
+30
View File
@@ -31,3 +31,33 @@ export async function sendCommandToThirdParty(topicData: string, payload: string
throw error throw error
} }
} }
export async function sendQueryToThirdParty(topicData: string) {
try {
const response = await fetch(`${httpConfig.baseUrl}/state-reply`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
topic: topicData,
}),
})
logger.info({ msg: 'Third-party query sent successfully', topic: topicData, status: response.status })
if (response.status != 200) {
return {
status: response.status,
message: response.statusText,
data: null,
}
}
return {
status: response.status,
message: response.statusText,
data: await response.json(),
}
} catch (error) {
logger.error({ msg: 'Failed to send query to third-party service', topic: topicData, error: (error as Error).message })
throw error
}
}
+25 -28
View File
@@ -1,9 +1,10 @@
import { sendQueryToThirdParty } from '../commands/command'
import { DeviceQueryParams } from '../schema' import { DeviceQueryParams } from '../schema'
export default abstract class QueryService { export default abstract class QueryService {
static async getDeviceStatus(query: DeviceQueryParams): Promise<{ static async getDeviceStatus(query: DeviceQueryParams): Promise<{
status: 'success' status: string
message: 'command accepted' message: string
data: { data: {
floorName: string floorName: string
unitNumber: string unitNumber: string
@@ -13,7 +14,7 @@ export default abstract class QueryService {
code: string code: string
towerNumber: string towerNumber: string
payload: string payload: string
} } | null
}> { }> {
// TODO: Check nonce for replay attack when DB is implemented // TODO: Check nonce for replay attack when DB is implemented
@@ -23,36 +24,32 @@ export default abstract class QueryService {
throw new Error('Unsupported device topic') throw new Error('Unsupported device topic')
} }
if (topic === 'SAVY/L2_01-BL-LV-S-S-T1') { const request = await sendQueryToThirdParty(topic)
if (request.status !== 200) {
throw new Error('Failed to get device status')
}
if (request.data.data == null) {
return {
status: 'error',
message: 'Device not found',
data: null,
}
}
return { return {
status: 'success', status: 'success',
message: 'command accepted', message: 'command accepted',
data: { data: {
floorName: 'L2', floorName: request.data.floor,
unitNumber: '01', unitNumber: request.data.unit,
deviceName: 'BL', deviceName: request.data.device,
roomName: 'LV', roomName: request.data.room,
deviceType: 'S', deviceType: request.data.devType,
code: 'S', code: request.data.code,
towerNumber: 'T1', towerNumber: request.data.tower,
payload: 'Open', payload: request.data.payload,
},
}
} else {
return {
status: 'success',
message: 'command accepted',
data: {
floorName: 'L2',
unitNumber: '01',
deviceName: 'L',
roomName: 'LV',
deviceType: 'S',
code: 'C',
towerNumber: 'T1',
payload: 'On',
}, },
} }
} }
} }
}
+3 -4
View File
@@ -33,12 +33,11 @@ export const router = new Elysia({
.get('/status', async ({ query, set }) => { .get('/status', async ({ query, set }) => {
try { try {
const result = await QueryService.getDeviceStatus(query) const result = await QueryService.getDeviceStatus(query)
if (result) { if (result.status == 'error' && result.message === 'Device not found') {
return result
} else {
set.status = 404 set.status = 404
return { status: 'not_found', message: 'Device status not found' } return { status: 'not_found', message: 'Device not found', data: null }
} }
return result
} catch (error) { } catch (error) {
if (error instanceof Error && error.message in deviceErrorResponseMap) { if (error instanceof Error && error.message in deviceErrorResponseMap) {
const { status, response } = deviceErrorResponseMap[error.message] const { status, response } = deviceErrorResponseMap[error.message]
+2 -2
View File
@@ -67,8 +67,8 @@ export const deviceCommandResponseSchema = {
// Query response schema // Query response schema
export const deviceQueryResponseSchema = { export const deviceQueryResponseSchema = {
200: z.object({ 200: z.object({
status: z.literal('success'), status: z.string(),
message: z.literal('command accepted'), message: z.string(),
data: z.object({ data: z.object({
floorName: z.string(), floorName: z.string(),
unitNumber: z.string(), unitNumber: z.string(),