feat: add pending vehicle association resolution UI (refs #160)
All checks were successful
Deploy to Staging / Build Images (pull_request) Successful in 8m40s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 52s
Deploy to Staging / Verify Staging (pull_request) Successful in 8s
Deploy to Staging / Notify Staging Ready (pull_request) Successful in 7s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
All checks were successful
Deploy to Staging / Build Images (pull_request) Successful in 8m40s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 52s
Deploy to Staging / Verify Staging (pull_request) Successful in 8s
Deploy to Staging / Notify Staging Ready (pull_request) Successful in 7s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
Backend: Add authenticated endpoints for pending association CRUD (GET/POST/DELETE /api/email-ingestion/pending). Service methods for resolving (creates fuel/maintenance record) and dismissing associations. Frontend: New email-ingestion feature with types, API client, hooks, PendingAssociationBanner (dashboard), PendingAssociationList, and ResolveAssociationDialog. Mobile-first responsive with 44px touch targets and full-screen dialogs on small screens. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,11 +1,12 @@
|
||||
/**
|
||||
* @ai-summary Resend inbound webhook route registration
|
||||
* @ai-context Public endpoint (no JWT auth) with rawBody for signature verification
|
||||
* @ai-summary Resend inbound webhook + user-facing pending association routes
|
||||
* @ai-context Public webhook (no JWT) + authenticated CRUD for pending vehicle associations
|
||||
*/
|
||||
|
||||
import { FastifyPluginAsync } from 'fastify';
|
||||
import { EmailIngestionController } from './email-ingestion.controller';
|
||||
|
||||
/** Public webhook route - no JWT auth, uses Svix signature verification */
|
||||
export const emailIngestionWebhookRoutes: FastifyPluginAsync = async (fastify) => {
|
||||
const controller = new EmailIngestionController();
|
||||
|
||||
@@ -22,3 +23,38 @@ export const emailIngestionWebhookRoutes: FastifyPluginAsync = async (fastify) =
|
||||
controller.handleInboundWebhook.bind(controller)
|
||||
);
|
||||
};
|
||||
|
||||
/** Authenticated user-facing routes for pending vehicle associations */
|
||||
export const emailIngestionRoutes: FastifyPluginAsync = async (fastify) => {
|
||||
const controller = new EmailIngestionController();
|
||||
|
||||
// GET /api/email-ingestion/pending - List pending associations for authenticated user
|
||||
fastify.get('/email-ingestion/pending', {
|
||||
preHandler: [fastify.authenticate],
|
||||
handler: controller.getPendingAssociations.bind(controller),
|
||||
});
|
||||
|
||||
// GET /api/email-ingestion/pending/count - Get count of pending associations
|
||||
fastify.get('/email-ingestion/pending/count', {
|
||||
preHandler: [fastify.authenticate],
|
||||
handler: controller.getPendingAssociationCount.bind(controller),
|
||||
});
|
||||
|
||||
// POST /api/email-ingestion/pending/:id/resolve - Resolve by selecting vehicle
|
||||
fastify.post<{ Params: { id: string }; Body: { vehicleId: string } }>(
|
||||
'/email-ingestion/pending/:id/resolve',
|
||||
{
|
||||
preHandler: [fastify.authenticate],
|
||||
handler: controller.resolveAssociation.bind(controller),
|
||||
}
|
||||
);
|
||||
|
||||
// DELETE /api/email-ingestion/pending/:id - Dismiss/discard a pending association
|
||||
fastify.delete<{ Params: { id: string } }>(
|
||||
'/email-ingestion/pending/:id',
|
||||
{
|
||||
preHandler: [fastify.authenticate],
|
||||
handler: controller.dismissAssociation.bind(controller),
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user