feat: TTLock API server selector (EU vs China) + pass apiServer to agent
- Add api_server column to hotel_ttlock_config (migration 053) - GET/PATCH config includes apiServer field - issue-card passes apiServer to agent command - Agent: WriteCardCmd.apiServer optional, all API calls use it - TTLockPage: radio buttons EU/China with hint about 404 error Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
3
backend/migrations/053_ttlock_api_server.sql
Normal file
3
backend/migrations/053_ttlock_api_server.sql
Normal file
@@ -0,0 +1,3 @@
|
||||
-- TTLock: выбор сервера API (EU или China)
|
||||
ALTER TABLE hotel_ttlock_config
|
||||
ADD COLUMN IF NOT EXISTS api_server TEXT NOT NULL DEFAULT 'https://euopen.ttlock.com';
|
||||
@@ -47,17 +47,18 @@ const ttlockRoutes: FastifyPluginAsync = async (fastify) => {
|
||||
if (!hotelId) return reply.code(404).send({ error: 'Hotel not found' })
|
||||
|
||||
const { rows } = await db.query(
|
||||
`SELECT is_enabled, client_id, card_sectors FROM hotel_ttlock_config WHERE hotel_id = $1`,
|
||||
`SELECT is_enabled, client_id, card_sectors, api_server FROM hotel_ttlock_config WHERE hotel_id = $1`,
|
||||
[hotelId],
|
||||
)
|
||||
if (!rows[0]) {
|
||||
return { isEnabled: false, clientId: '', cardSectors: '1,2,3,4,5,6,7,8,9,10' }
|
||||
return { isEnabled: false, clientId: '', cardSectors: '1,2,3,4,5,6,7,8,9,10', apiServer: 'https://euopen.ttlock.com' }
|
||||
}
|
||||
const r = rows[0]
|
||||
return {
|
||||
isEnabled: r.is_enabled,
|
||||
clientId: r.client_id,
|
||||
cardSectors: r.card_sectors,
|
||||
apiServer: r.api_server ?? 'https://euopen.ttlock.com',
|
||||
}
|
||||
})
|
||||
|
||||
@@ -68,6 +69,7 @@ const ttlockRoutes: FastifyPluginAsync = async (fastify) => {
|
||||
client_id?: string
|
||||
client_secret?: string
|
||||
card_sectors?: string
|
||||
api_server?: string
|
||||
}
|
||||
}>('/api/hotels/:slug/ttlock/config', { onRequest: [fastify.authenticate] }, async (req, reply) => {
|
||||
const { slug } = req.params
|
||||
@@ -76,16 +78,17 @@ const ttlockRoutes: FastifyPluginAsync = async (fastify) => {
|
||||
const hotelId = await getHotelId(slug)
|
||||
if (!hotelId) return reply.code(404).send({ error: 'Hotel not found' })
|
||||
|
||||
const { is_enabled: isEnabled, client_id: clientId, client_secret: clientSecret, card_sectors: cardSectors } = req.body
|
||||
const { is_enabled: isEnabled, client_id: clientId, client_secret: clientSecret, card_sectors: cardSectors, api_server: apiServer } = req.body
|
||||
|
||||
await db.query(
|
||||
`INSERT INTO hotel_ttlock_config (hotel_id, is_enabled, client_id, client_secret, card_sectors)
|
||||
VALUES ($1, $2, $3, $4, $5)
|
||||
`INSERT INTO hotel_ttlock_config (hotel_id, is_enabled, client_id, client_secret, card_sectors, api_server)
|
||||
VALUES ($1, $2, $3, $4, $5, $6)
|
||||
ON CONFLICT (hotel_id) DO UPDATE SET
|
||||
is_enabled = COALESCE($2, hotel_ttlock_config.is_enabled),
|
||||
client_id = COALESCE($3, hotel_ttlock_config.client_id),
|
||||
client_secret = COALESCE(NULLIF($4, ''), hotel_ttlock_config.client_secret),
|
||||
card_sectors = COALESCE($5, hotel_ttlock_config.card_sectors),
|
||||
api_server = COALESCE($6, hotel_ttlock_config.api_server),
|
||||
updated_at = NOW()`,
|
||||
[
|
||||
hotelId,
|
||||
@@ -93,6 +96,7 @@ const ttlockRoutes: FastifyPluginAsync = async (fastify) => {
|
||||
clientId ?? null,
|
||||
clientSecret ?? '',
|
||||
cardSectors ?? null,
|
||||
apiServer ?? null,
|
||||
],
|
||||
)
|
||||
return { ok: true }
|
||||
@@ -322,6 +326,7 @@ const ttlockRoutes: FastifyPluginAsync = async (fastify) => {
|
||||
cardSectors: cfg.card_sectors,
|
||||
clientId: cfg.client_id,
|
||||
clientSecret: cfg.client_secret,
|
||||
apiServer: cfg.api_server ?? 'https://euopen.ttlock.com',
|
||||
startDate: checkIn,
|
||||
endDate: checkOut,
|
||||
}, 30_000)
|
||||
|
||||
Reference in New Issue
Block a user