Mode2Test/AuthAndToken: assume tokens always fresh with background refresh; fix jobs API to use correct collection; align Home UI to Mode1 (exact fields, styling, strict Active dot); add full-field IndexedDB cache w/ pagination; remove progress bar; dev TLS bypass; rebuild bundles
This commit is contained in:
@@ -0,0 +1,104 @@
|
||||
import { Hono } from 'hono';
|
||||
import type { Context } from 'hono';
|
||||
import { tokenService } from './token-service';
|
||||
|
||||
// PERMANENT: Jobs API routes
|
||||
// Provides access to job data from PocketBase
|
||||
// Requires authentication (valid PB token)
|
||||
//
|
||||
// Dependencies:
|
||||
// - tokenService for PB token retrieval
|
||||
// - process.env.POCKETBASE_URL for PB API endpoint
|
||||
const JOBS_COLLECTION = 'pbc_1407612689';
|
||||
//
|
||||
// Endpoints:
|
||||
// - GET /api/jobs - List jobs with pagination, filtering, field selection
|
||||
|
||||
export function createJobsRoutes(): Hono {
|
||||
const router = new Hono();
|
||||
|
||||
// GET /api/jobs - Fetch jobs from PocketBase
|
||||
// Query params:
|
||||
// - page: Page number (default 1)
|
||||
// - perPage: Items per page (default 50, max 1000)
|
||||
// - fields: Comma-separated field names to return (optional, for cache optimization)
|
||||
// - filter: PocketBase filter syntax (optional)
|
||||
// - sort: Sort field (default -Job_Number)
|
||||
router.get('/', async (c: Context) => {
|
||||
try {
|
||||
// Get token (assume present after login)
|
||||
const tokens = await tokenService.getTokens();
|
||||
const pbToken = tokens?.pbToken;
|
||||
|
||||
// Parse query params
|
||||
const page = parseInt(c.req.query('page') || '1');
|
||||
const perPage = Math.min(parseInt(c.req.query('perPage') || '50'), 1000);
|
||||
const fields = c.req.query('fields'); // Optional: comma-separated field names
|
||||
const filter = c.req.query('filter'); // Optional: PocketBase filter
|
||||
const sort = c.req.query('sort') || '-Job_Number';
|
||||
|
||||
// Build PocketBase API URL
|
||||
const pbUrl = new URL(`${process.env.POCKETBASE_URL}/api/collections/${JOBS_COLLECTION}/records`);
|
||||
pbUrl.searchParams.set('page', page.toString());
|
||||
pbUrl.searchParams.set('perPage', perPage.toString());
|
||||
pbUrl.searchParams.set('sort', sort);
|
||||
|
||||
if (fields) {
|
||||
pbUrl.searchParams.set('fields', fields);
|
||||
}
|
||||
|
||||
if (filter) {
|
||||
pbUrl.searchParams.set('filter', filter);
|
||||
}
|
||||
|
||||
// Fetch from PocketBase
|
||||
// temporary: dev-only SSL bypass; global rejectUnauthorized already set, keep here as explicit
|
||||
const response = await fetch(pbUrl.toString(), {
|
||||
headers: pbToken ? { 'Authorization': `Bearer ${pbToken}` } : {},
|
||||
// @ts-ignore Bun TLS option
|
||||
tls: { rejectUnauthorized: false }
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const errorText = await response.text();
|
||||
console.error('PocketBase jobs fetch failed:', response.status, errorText);
|
||||
return c.json({ error: 'Failed to fetch jobs from PocketBase' }, response.status);
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
return c.json(data);
|
||||
} catch (err) {
|
||||
console.error('Jobs API error:', (err as Error)?.message);
|
||||
return c.json({ error: 'Internal server error' }, 500);
|
||||
}
|
||||
});
|
||||
|
||||
// GET /api/jobs/:id - Fetch single job by ID
|
||||
router.get('/:id', async (c: Context) => {
|
||||
try {
|
||||
// Check authentication
|
||||
const tokens = await tokenService.getTokens();
|
||||
const pbToken = tokens?.pbToken;
|
||||
|
||||
const jobId = c.req.param('id');
|
||||
const pbUrl = `${process.env.POCKETBASE_URL}/api/collections/${JOBS_COLLECTION}/records/${jobId}`;
|
||||
|
||||
// Fetch from PocketBase
|
||||
const response = await fetch(pbUrl, {
|
||||
headers: pbToken ? { 'Authorization': `Bearer ${pbToken}` } : {}
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
return c.json({ error: 'Job not found' }, 404);
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
return c.json(data);
|
||||
} catch (err) {
|
||||
console.error('Job fetch error:', (err as Error)?.message);
|
||||
return c.json({ error: 'Internal server error' }, 500);
|
||||
}
|
||||
});
|
||||
|
||||
return router;
|
||||
}
|
||||
Reference in New Issue
Block a user