-
Notifications
You must be signed in to change notification settings - Fork 21
Feat/dashboard integration demo #468
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
- Preserve URL path when processing tokens instead of always redirecting to root
- Add NotFound component for better UX on invalid routes
- Enable proper deep linking to portal routes like /new and /destinations/{id}
This allows external applications to redirect users to specific portal pages
while maintaining authentication flow.
Add a comprehensive Next.js dashboard demo that showcases seamless integration
with Outpost event destinations management.
Key Features:
- User authentication with NextAuth.js and PostgreSQL
- Auto-creation of Outpost tenants on user registration
- Dashboard overview showing tenant statistics from Outpost API
- Seamless redirect to Outpost portal for destination management
- Support for deep linking to specific portal pages (/new, /destinations/{id})
- Clickable destinations list with navigation to individual destination details
- Docker Compose setup with PostgreSQL, Redis, RabbitMQ, and Outpost services
Technical Implementation:
- Next.js 15 with App Router and TypeScript
- Tailwind CSS for styling
- NextAuth.js v5 with JWT tokens
- Official Outpost TypeScript SDK integration
- Middleware-based authentication and route protection
- Catch-all route handlers for flexible portal path support
This demo demonstrates how to integrate Outpost with an API platform or
SaaS dashboard, providing users with a seamless experience between the
main application and event destination management.
Replace console.log debugging with proper structured logging using Winston: - Add winston logger with configurable LOG_LEVEL environment variable - Replace all console.log/error statements with structured logging - Remove verbose debug logging from API routes - Keep valuable operational logging (errors, tenant operations, user events) - Add log level configuration to environment documentation Logging levels available: - error: Critical issues only - warn: Warnings and errors - info: General information (default) - debug: Detailed debugging information This provides better observability while reducing noise in production.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
… playground and API endpoints - Added interactive event testing playground for publishing events to destinations - Implemented API endpoint for triggering test events - Created API endpoint for fetching available topics - Updated dashboard structure to include playground navigation - Improved user experience with form validation and error handling in playground - Refactored destination and topic fetching into custom hooks - Enhanced overall documentation to reflect new features and usage
…reflect available topics for selected destination
…nce in INTEGRATION_DETAILS.md
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This pull request introduces a comprehensive dashboard integration demo for API platforms, showcasing how to seamlessly embed Outpost's event destination management capabilities into existing SaaS dashboards. The demo provides a full-stack Next.js application with automatic tenant provisioning, authentication integration, and a complete development environment using Docker Compose.
- Complete Next.js dashboard application with user registration, authentication, and portal integration
- Infrastructure-as-code setup with Docker Compose orchestrating PostgreSQL, Redis, RabbitMQ, and Outpost services
- Comprehensive documentation and implementation guides for real-world integration patterns
Reviewed Changes
Copilot reviewed 52 out of 59 changed files in this pull request and generated 5 comments.
| File | Description |
|---|---|
| internal/portal/src/app.tsx | Fixed portal navigation to preserve current path during token redirects and added 404 handling |
| examples/demos/dashboard-integration/ | New comprehensive demo with authentication, dashboard, playground, and full infrastructure setup |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
| // Preserve the current path from the browser | ||
| const currentPath = window.location.pathname; | ||
| window.location.replace(currentPath); |
Copilot
AI
Sep 2, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This logic is flawed - if the user is already on the correct path, this will cause an unnecessary page reload and potential infinite redirect loop. The code should check if the current path differs from the root path before redirecting, or use a different approach like removing the token parameter from the URL.
| // Preserve the current path from the browser | |
| const currentPath = window.location.pathname; | |
| window.location.replace(currentPath); | |
| // Remove the token parameter from the URL without reloading unnecessarily | |
| searchParams.delete("token"); | |
| const newSearch = searchParams.toString(); | |
| const newUrl = window.location.pathname + (newSearch ? `?${newSearch}` : ""); | |
| if (window.location.search.includes("token")) { | |
| window.location.replace(newUrl); | |
| } |
| const outpost = getOutpostClient(); | ||
| const result = await outpost.tenants.getPortalUrl({ | ||
| tenantId, | ||
| theme: theme as any, // SDK accepts theme as string but types are restrictive |
Copilot
AI
Sep 2, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using 'as any' bypasses TypeScript's type safety. Consider using proper type assertion like 'theme as "light" | "dark"' or create a proper type guard to validate the theme parameter before passing it to the SDK.
| // Handle SDK validation error - the API response is valid but SDK expects different format | ||
| if (error && typeof error === "object" && "rawValue" in error) { | ||
| const rawResponse = (error as any).rawValue; |
Copilot
AI
Sep 2, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This error handling pattern is brittle and tightly coupled to SDK implementation details. Consider using a more robust approach with proper error type checking or wrapping the SDK calls in a try-catch that handles known error patterns more explicitly.
| // Handle SDK validation error - the API response is valid but SDK expects different format | |
| if (error && typeof error === "object" && "rawValue" in error) { | |
| const rawResponse = (error as any).rawValue; | |
| // More robust error handling: check for error type or code before falling back to property checks | |
| if ( | |
| error && | |
| typeof error === "object" && | |
| ( | |
| // Prefer error.name or error.code if available | |
| (error.name === "OutpostValidationError") || | |
| (error.code === "VALIDATION_ERROR") || | |
| // Fallback to rawValue property if necessary | |
| ("rawValue" in error) | |
| ) | |
| ) { | |
| const rawResponse = (error as any).rawValue ?? (error as any).response ?? null; |
| <div className="space-y-4"> | ||
| {events.slice(0, 5).map((event, index) => ( | ||
| <div | ||
| key={`${event.id}-${(event as any).destination_id || index}`} |
Copilot
AI
Sep 2, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using 'as any' bypasses type safety. If destination_id is an expected property, it should be added to the Event interface. If it's optional or uncertain, use optional chaining or proper type guards instead.
| key={`${event.id}-${(event as any).destination_id || index}`} | |
| key={`${event.id}-${event.destination_id ?? index}`} |
| </Badge> | ||
| </div> | ||
| <p className="text-xs text-gray-500 mt-1"> | ||
| {formatDateTime((event as any).time || event.createdAt)} |
Copilot
AI
Sep 2, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another 'as any' usage that should be avoided. If 'time' is a valid property on events, add it to the Event interface. Otherwise, use proper type checking or default to createdAt without casting.
| {formatDateTime((event as any).time || event.createdAt)} | |
| {formatDateTime('time' in event && event.time ? event.time : event.createdAt)} |
TODO:
This pull request introduces a new demo project for API platform dashboard integration with Outpost, providing a full-featured Next.js application, infrastructure-as-code for local development, and seamless Outpost event management integration. The PR includes configuration, environment, and documentation files, as well as boilerplate code for authentication, registration, and linting.
The most important changes are:
Project Setup & Documentation
README.mddescribing features, setup, architecture, usage, and integration patterns for the dashboard integration demo.package.jsonwith all necessary dependencies for Next.js, Outpost SDK, authentication, database, and development tooling.Environment & Configuration
.env.example) and Outpost (.env.outpost.example), detailing all required configuration variables. [1] [2].gitignoretailored for Next.js, Node, Docker, and environment files..prettierrc), ESLint (eslint.config.mjs), and Next.js (next.config.ts) for code style and linting. [1] [2] [3]postcss.config.mjsfor Tailwind CSS integration.Infrastructure & Database
docker-compose.ymlto orchestrate PostgreSQL, Redis, RabbitMQ, and Outpost services for local development and testing.init-databases.sqlto initialize separate databases and users for the dashboard and Outpost, including schema and permissions setup.Authentication & User Registration
src/app/api/auth/[...nextauth]/route.ts. (examples/demos/dashboard-integration/src/app/api/auth/[...nextauth]/route.tsR1-R3)