Workforce: add location_id config field + locations fetch endpoint
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
24f3fcdc7b
commit
db1b168300
2 changed files with 26 additions and 1 deletions
|
|
@ -29,7 +29,7 @@ export const INTEGRATIONS = {
|
||||||
},
|
},
|
||||||
workforce: {
|
workforce: {
|
||||||
name: 'Workforce',
|
name: 'Workforce',
|
||||||
configFields: ['base_url', 'sync_hours'],
|
configFields: ['base_url', 'sync_hours', 'location_id'],
|
||||||
secretFields: ['bearer_token'],
|
secretFields: ['bearer_token'],
|
||||||
},
|
},
|
||||||
smtp: {
|
smtp: {
|
||||||
|
|
|
||||||
|
|
@ -112,6 +112,31 @@ export async function integrationRoutes(app) {
|
||||||
})
|
})
|
||||||
|
|
||||||
// POST /settings/api/integrations/newbook/sync-rooms
|
// POST /settings/api/integrations/newbook/sync-rooms
|
||||||
|
// GET /settings/api/integrations/workforce/locations — fetch location list from Tanda for the picker
|
||||||
|
app.get('/integrations/workforce/locations', { preHandler: requireAdmin }, async (req, reply) => {
|
||||||
|
const { rows: [row] } = await pool.query(`SELECT * FROM integrations WHERE slug = 'workforce'`)
|
||||||
|
if (!row?.enabled) return reply.status(400).send({ error: 'Workforce integration not enabled' })
|
||||||
|
const creds = { ...row.config, ...decryptSecrets(row) }
|
||||||
|
if (!creds.bearer_token) return reply.status(400).send({ error: 'Workforce bearer token not configured' })
|
||||||
|
const baseUrl = creds.base_url || 'https://my.tanda.co'
|
||||||
|
|
||||||
|
const locations = []
|
||||||
|
let page = 1
|
||||||
|
while (true) {
|
||||||
|
const res = await fetch(`${baseUrl}/api/v2/locations?page=${page}&page_size=100`, {
|
||||||
|
headers: { Authorization: `Bearer ${creds.bearer_token}` },
|
||||||
|
signal: AbortSignal.timeout(8000),
|
||||||
|
})
|
||||||
|
if (!res.ok) return reply.status(502).send({ error: `Workforce API error (${res.status})` })
|
||||||
|
const data = await res.json()
|
||||||
|
const items = Array.isArray(data) ? data : (data.locations ?? [])
|
||||||
|
locations.push(...items.map(l => ({ id: String(l.id), name: l.name, short_name: l.short_name ?? null })))
|
||||||
|
if (items.length < 100) break
|
||||||
|
page++
|
||||||
|
}
|
||||||
|
return locations
|
||||||
|
})
|
||||||
|
|
||||||
app.post('/integrations/newbook/sync-rooms', { preHandler: requireAdmin }, async (req, reply) => {
|
app.post('/integrations/newbook/sync-rooms', { preHandler: requireAdmin }, async (req, reply) => {
|
||||||
const { rows: [row] } = await pool.query(`SELECT * FROM integrations WHERE slug = 'newbook'`)
|
const { rows: [row] } = await pool.query(`SELECT * FROM integrations WHERE slug = 'newbook'`)
|
||||||
if (!row?.enabled) return reply.status(400).send({ error: 'Newbook integration not enabled' })
|
if (!row?.enabled) return reply.status(400).send({ error: 'Newbook integration not enabled' })
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue