npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@fatagnus/convex-feedback

v0.2.18

Published

Bug reports and feedback collection component for Convex applications with AI analysis and email notifications

Readme

@fatagnus/convex-feedback

Bug reports and feedback collection component for Convex applications with AI analysis, email notifications, and a REST API.

Features

  • 🐛 Bug Reports - Capture bug reports with browser diagnostics, console errors, and screenshots
  • 💬 Feedback - Collect feature requests, change requests, and general feedback
  • 🤖 AI Analysis - Automatic analysis of submissions using OpenRouter/Claude
  • 💬 AI Interview Mode - Conversational AI interviews to help users articulate detailed bug reports and feedback
  • 📧 Email Notifications - Send notifications to reporters and support teams via Resend
  • 👥 Support Teams - Route notifications to the right teams based on type/severity
  • 📸 Screenshots - Capture or upload screenshots with reports
  • 🔄 Real-time - Leverages Convex for real-time updates
  • 🎫 Ticket Numbers - Human-readable ticket IDs (BUG-2025-0001, FB-2025-0001)
  • 🔑 API Keys - Secure API key management for external integrations
  • 🌐 REST API - HTTP endpoints for external tools (Codebuff, CLI tools, etc.)

Installation

npm install @fatagnus/convex-feedback

Peer Dependencies

Required:

  • convex (>=1.17.0)
  • react (>=18.0.0)

Optional (for React components):

  • @mantine/core (>=7.0.0)
  • @mantine/form (>=7.0.0)
  • @mantine/hooks (>=7.0.0)
  • @mantine/notifications (>=7.0.0)
  • @tabler/icons-react (>=3.0.0)
  • html2canvas (>=1.4.0)

Optional (for AI analysis and interview mode):

  • @convex-dev/agent (>=0.1.0)
  • @ai-sdk/openai-compatible (>=0.1.0)
  • zod (>=3.0.0)

Optional (for email notifications):

  • resend (>=4.0.0)

Setup

1. Add the Component

Add the feedback component to your Convex app configuration:

// convex/convex.config.ts
import { defineApp } from "convex/server";
import feedback from "@fatagnus/convex-feedback/convex.config";

const app = defineApp();
app.use(feedback);
export default app;

2. Register HTTP Routes (Optional)

To enable the REST API for external integrations:

// convex/http.ts
import { httpRouter } from "convex/server";
import { registerFeedbackRoutes } from "@fatagnus/convex-feedback";

const http = httpRouter();

// Register feedback API routes with optional prefix
registerFeedbackRoutes(http, { pathPrefix: "/feedback" });

// Your other routes...
export default http;

3. Configure Environment Variables

Set these environment variables in your Convex dashboard:

| Variable | Required | Description | |----------|----------|-------------| | OPENROUTER_API_KEY | No | OpenRouter API key for AI analysis | | RESEND_API_KEY | No | Resend API key for email notifications | | RESEND_FROM_EMAIL | No | From email address (default: [email protected]) |

4. Add React Components

Wrap your app with the BugReportProvider and add the BugReportButton:

import { BugReportProvider, BugReportButton } from '@fatagnus/convex-feedback/react';
import { api } from './convex/_generated/api';

function App() {
  const user = useCurrentUser(); // Your auth hook

  return (
    <BugReportProvider>
      <YourApp />
      
      {user && (
        <BugReportButton
          reporterType="staff"
          reporterId={user.id}
          reporterEmail={user.email}
          reporterName={user.name}
          bugReportApi={{
            create: api.feedback.bugReports.create,
            generateUploadUrl: api.feedback.bugReports.generateUploadUrl,
          }}
          feedbackApi={{
            create: api.feedback.feedback.create,
            generateUploadUrl: api.feedback.feedback.generateUploadUrl,
          }}
        />
      )}
    </BugReportProvider>
  );
}

HTTP REST API

The REST API allows external tools (like Codebuff, CLI tools, CI/CD pipelines) to interact with bug reports and feedback.

Authentication

All endpoints require an API key in the Authorization header:

Authorization: Bearer fb_your_api_key_here

Base URL

Your Convex HTTP endpoint + the path prefix you configured:

https://your-deployment.convex.site/feedback/api/...

Ticket Number Format

All tickets have human-readable IDs:

| Type | Format | Example | |------|--------|----------| | Bug Report | BUG-YYYY-NNNN | BUG-2025-0001 | | Feedback | FB-YYYY-NNNN | FB-2025-0042 |


API Key Management

API keys are managed via Convex mutations. The full key is only shown once at creation time.

Create a Key

const result = await ctx.runMutation(api.feedback.apiKeys.create, {
  name: "My Integration",
  expiresAt: Date.now() + 90 * 24 * 60 * 60 * 1000, // 90 days (optional)
});

console.log(result.key);       // fb_a1b2c3d4e5f6g7h8... (save this!)
console.log(result.keyPrefix); // fb_a1b2c3d4

List Keys

const keys = await ctx.runQuery(api.feedback.apiKeys.list, {});
// Returns array of { _id, keyPrefix, name, expiresAt, isRevoked, isExpired, createdAt }

Revoke a Key

await ctx.runMutation(api.feedback.apiKeys.revoke, {
  keyPrefix: "fb_a1b2c3d4",
});

Rotate a Key

const newKey = await ctx.runMutation(api.feedback.apiKeys.rotate, {
  keyPrefix: "fb_a1b2c3d4",
  name: "Rotated Key", // optional
  expiresAt: Date.now() + 90 * 24 * 60 * 60 * 1000, // optional
});

Endpoints

GET /api/items

List bug reports and/or feedback items with optional filters.

Query Parameters:

| Parameter | Type | Default | Description | |-----------|------|---------|-------------| | itemType | bug | feedback | all | all | Filter by item type | | status | string | - | Filter by status | | severity | low | medium | high | critical | - | Filter bugs by severity | | priority | nice_to_have | important | critical | - | Filter feedback by priority | | type | feature_request | change_request | general | - | Filter feedback by type | | limit | number | 50 | Max items to return | | includeArchived | true | false | false | Include archived items |

Bug Status Values: open, in-progress, resolved, closed

Feedback Status Values: open, under_review, planned, in_progress, completed, declined

Example:

# List all open bugs
curl -H "Authorization: Bearer fb_your_key" \
  "https://your-site.convex.site/feedback/api/items?itemType=bug&status=open"

Response:

{
  "bugs": [
    {
      "_id": "abc123",
      "ticketNumber": "BUG-2025-0001",
      "title": "Login button not working",
      "severity": "high",
      "status": "open",
      ...
    }
  ],
  "feedback": [...]
}

GET /api/items/{ticketNumber}

Fetch a single bug report or feedback item by ticket number.

Example:

curl -H "Authorization: Bearer fb_your_key" \
  "https://your-site.convex.site/feedback/api/items/BUG-2025-0001"

Response:

{
  "type": "bug",
  "_id": "abc123",
  "ticketNumber": "BUG-2025-0001",
  "title": "Login button not working",
  "description": "When I click the login button, nothing happens",
  "severity": "high",
  "status": "open",
  "aiSummary": "The login form submit handler is not properly bound",
  "aiRootCauseAnalysis": "React event handler not attached correctly",
  "aiSuggestedFix": "Check that the onClick handler is properly bound",
  ...
}

GET /api/prompt/{ticketNumber}

Fetch an AI-generated prompt for fixing/implementing a ticket. Designed for AI coding assistants like Codebuff.

Query Parameters:

| Parameter | Type | Default | Description | |-----------|------|---------|-------------| | template | fix | implement | analyze | codebuff | fix (bugs) / implement (feedback) | Prompt template |

Templates:

| Template | Use Case | |----------|----------| | fix | Bug fix instructions | | implement | Feature implementation instructions | | analyze | Deep analysis prompt | | codebuff | Codebuff-optimized structured format |

Example:

# Get a Codebuff-optimized prompt
curl -H "Authorization: Bearer fb_your_key" \
  "https://your-site.convex.site/feedback/api/prompt/BUG-2025-0001?template=codebuff"

Response:

{
  "ticketNumber": "BUG-2025-0001",
  "type": "bug",
  "template": "codebuff",
  "prompt": "# Bug Fix Request: BUG-2025-0001\n\n## Title\nLogin button not working\n\n..."
}

PATCH /api/items/{ticketNumber}/status

Update the status of a bug report or feedback item.

Request Body:

{ "status": "resolved" }

Example:

curl -X PATCH \
  -H "Authorization: Bearer fb_your_key" \
  -H "Content-Type: application/json" \
  -d '{"status": "resolved"}' \
  "https://your-site.convex.site/feedback/api/items/BUG-2025-0001/status"

Response:

{ "success": true, "ticketNumber": "BUG-2025-0001" }

PATCH /api/items/{ticketNumber}/archive

Archive or unarchive a bug report or feedback item.

Request Body:

{ "archived": true }

Example:

curl -X PATCH \
  -H "Authorization: Bearer fb_your_key" \
  -H "Content-Type: application/json" \
  -d '{"archived": true}' \
  "https://your-site.convex.site/feedback/api/items/BUG-2025-0001/archive"

Response:

{ "success": true, "ticketNumber": "BUG-2025-0001", "isArchived": true }

Error Responses

| Status | Response | |--------|----------| | 400 | { "error": "Bad request", "message": "..." } | | 401 | { "error": "Unauthorized", "message": "Invalid or missing API key" } | | 404 | { "error": "Not found", "message": "Bug report BUG-2025-0001 not found" } |


Integration Examples

Codebuff Integration

curl -s -H "Authorization: Bearer fb_your_key" \
  "https://your-site.convex.site/feedback/api/prompt/BUG-2025-0001?template=codebuff" \
  | jq -r '.prompt' \
  | codebuff

GitHub Actions

- name: Get open bugs count
  run: |
    curl -s -H "Authorization: Bearer ${{ secrets.FEEDBACK_API_KEY }}" \
      "${{ secrets.CONVEX_SITE_URL }}/feedback/api/items?itemType=bug&status=open" \
      | jq '.bugs | length'

Convex API Reference

Bug Reports

bugReports.create

Create a new bug report.

const bugReportId = await ctx.runMutation(api.feedback.bugReports.create, {
  title: "Button not working",
  description: "The submit button doesn't respond to clicks",
  severity: "high", // low | medium | high | critical
  reporterType: "staff", // staff | customer
  reporterId: "user_123",
  reporterEmail: "[email protected]",
  reporterName: "John Doe",
  url: "https://app.example.com/form",
  route: "/form",
  browserInfo: JSON.stringify({ userAgent: "..." }),
  consoleErrors: JSON.stringify([{ message: "Error..." }]),
  screenshotStorageId: "storage_id_here", // optional
  viewportWidth: 1920,
  viewportHeight: 1080,
  networkState: "online",
});

bugReports.list

List bug reports with optional filters.

const reports = await ctx.runQuery(api.feedback.bugReports.list, {
  status: "open", // optional: open | in-progress | resolved | closed
  severity: "high", // optional: low | medium | high | critical
  includeArchived: false, // optional, default: false
  limit: 50, // optional, default: 50
});

bugReports.get

Get a single bug report by ID.

const report = await ctx.runQuery(api.feedback.bugReports.get, {
  reportId: "bug_report_id",
});

bugReports.updateStatus

Update the status of a bug report.

await ctx.runMutation(api.feedback.bugReports.updateStatus, {
  reportId: "bug_report_id",
  status: "resolved",
});

bugReports.archive / bugReports.unarchive

Archive or unarchive a bug report.

await ctx.runMutation(api.feedback.bugReports.archive, {
  reportId: "bug_report_id",
});

Feedback

feedback.create

Create new feedback.

const feedbackId = await ctx.runMutation(api.feedback.feedback.create, {
  type: "feature_request", // feature_request | change_request | general
  title: "Dark mode support",
  description: "Please add dark mode to reduce eye strain",
  priority: "important", // nice_to_have | important | critical
  reporterType: "customer",
  reporterId: "customer_123",
  reporterEmail: "[email protected]",
  reporterName: "Jane Doe",
  url: "https://app.example.com/settings",
  browserInfo: JSON.stringify({ userAgent: "..." }),
  viewportWidth: 1920,
  viewportHeight: 1080,
  networkState: "online",
});

feedback.list

List feedback with optional filters.

const items = await ctx.runQuery(api.feedback.feedback.list, {
  status: "open", // optional
  type: "feature_request", // optional
  priority: "important", // optional
  includeArchived: false, // optional
  limit: 50, // optional
});

Support Teams

supportTeams.create

Create a support team for notification routing.

const teamId = await ctx.runMutation(api.feedback.supportTeams.create, {
  teamName: "Engineering Team",
  memberEmails: ["[email protected]", "[email protected]"],
  feedbackTypes: ["feature_request", "change_request"],
  bugReportSeverities: ["high", "critical"],
});

supportTeams.list

List all support teams.

const teams = await ctx.runQuery(api.feedback.supportTeams.list, {
  activeOnly: true, // optional
});

supportTeams.update

Update a support team.

await ctx.runMutation(api.feedback.supportTeams.update, {
  teamId: "team_id",
  teamName: "Updated Team Name",
  memberEmails: ["[email protected]"],
  isActive: true,
});

React Components

BugReportProvider

Provider component that captures console errors for bug reports. Wrap your app with this provider.

import { BugReportProvider } from '@fatagnus/convex-feedback/react';

function App() {
  return (
    <BugReportProvider maxErrors={20}>
      <YourApp />
    </BugReportProvider>
  );
}

Props:

| Prop | Type | Default | Description | |------|------|---------|-------------| | children | ReactNode | - | Child components | | maxErrors | number | 20 | Maximum console errors to capture |

BugReportButton

Floating action button for submitting bug reports and feedback.

import { BugReportButton } from '@fatagnus/convex-feedback/react';

<BugReportButton
  reporterType="staff"
  reporterId={user.id}
  reporterEmail={user.email}
  reporterName={user.name}
  bugReportApi={{
    create: api.feedback.bugReports.create,
    generateUploadUrl: api.feedback.bugReports.generateUploadUrl,
  }}
  feedbackApi={{
    create: api.feedback.feedback.create,
    generateUploadUrl: api.feedback.feedback.generateUploadUrl,
  }}
  position={{ bottom: 20, right: 20 }}
  buttonColor="red"
  showFeedback={true}
  onSuccess={(type) => console.log(`${type} submitted`)}
  onError={(error, type) => console.error(`${type} failed:`, error)}
  // AI Interview Mode (optional)
  enableInterview={true}
  defaultMode="interview"
  interviewApi={{
    startBugInterview: api.feedback.agents.feedbackInterviewAgent.startBugInterview,
    startFeedbackInterview: api.feedback.agents.feedbackInterviewAgent.startFeedbackInterview,
    continueInterview: api.feedback.agents.feedbackInterviewAgent.continueInterview,
    getPendingForThread: api.feedback.inputRequests.getPendingForThread,
    getSessionByThread: api.feedback.agents.feedbackInterviewAgent.getSessionByThread,
  }}
  interviewContext={{
    appName: 'My App',
    appDescription: 'A productivity tool for teams',
    featureAreas: [
      { name: 'Dashboard', description: 'Main overview page' },
      { name: 'Reports', description: 'Analytics and reporting' },
    ],
  }}
/>

Props:

| Prop | Type | Default | Description | |------|------|---------|-------------| | reporterType | 'staff' \| 'customer' | - | Type of reporter | | reporterId | string | - | Unique reporter identifier | | reporterEmail | string | - | Reporter's email | | reporterName | string | - | Reporter's display name | | bugReportApi | object | - | Convex API references for bug reports | | feedbackApi | object | - | Convex API references for feedback | | position | object | { bottom: 20, right: 20 } | FAB position | | buttonColor | string | 'red' | Button color | | showFeedback | boolean | true | Show feedback tab | | onSuccess | function | - | Success callback | | onError | function | - | Error callback | | enableInterview | boolean | false | Enable AI interview mode | | defaultMode | 'form' \| 'interview' | 'form' | Default input mode when interview is enabled | | interviewContext | InterviewContext | - | Context to help AI ask better questions | | interviewApi | object | - | Convex API references for interview actions (required if enableInterview is true) |

ErrorBugReportButton

A self-contained bug report button designed for error pages. Pre-fills error details and allows users to submit bug reports directly from error boundaries or error pages.

import { ErrorBugReportButton } from '@fatagnus/convex-feedback/react';
import { api } from './convex/_generated/api';

function ErrorPage({ error }: { error: Error }) {
  return (
    <div>
      <h1>Something went wrong</h1>
      <p>{error.message}</p>
      
      <ErrorBugReportButton
        error={error}
        reporterType="staff"
        reporterId={user?.id}
        reporterEmail={user?.email}
        reporterName={user?.name}
        bugReportApi={{
          create: api.feedback.bugReports.create,
        }}
        variant="outline"
        color="red"
        onSuccess={() => console.log('Bug report submitted')}
        onError={(err) => console.error('Failed to submit:', err)}
      />
    </div>
  );
}

Props:

| Prop | Type | Default | Description | |------|------|---------|-------------| | error | Error | - | The error to report (required) | | reporterType | 'staff' \| 'customer' | 'staff' | Type of reporter | | reporterId | string | 'error-page' | Unique reporter identifier | | reporterEmail | string | '[email protected]' | Reporter's email | | reporterName | string | 'Error Page Reporter' | Reporter's display name | | bugReportApi | object | - | Convex API reference with create mutation (required) | | variant | 'filled' \| 'outline' \| 'light' \| 'subtle' | 'outline' | Button variant | | color | string | 'red' | Button color | | onSuccess | function | - | Success callback | | onError | function | - | Error callback |

Note: Unlike BugReportButton, this component only requires the bugReportApi.create mutation (no generateUploadUrl needed since error pages typically don't include screenshots).

useBugReportContext

Hook to access the bug report context for error capture.

import { useBugReportContext } from '@fatagnus/convex-feedback/react';

function MyComponent() {
  const { getConsoleErrors, clearConsoleErrors } = useBugReportContext();
  
  const errors = getConsoleErrors();
  // ...
}

AI Interview Mode

The AI Interview Mode provides a conversational experience to help users articulate their bug reports and feedback more effectively. Instead of filling out a form, users chat with an AI that asks clarifying questions and generates a well-structured report.

Enabling Interview Mode

To enable AI interviews, you need:

  1. OPENROUTER_API_KEY environment variable set in your Convex dashboard
  2. The @convex-dev/agent and zod packages installed
  3. The enableInterview and interviewApi props configured
import { BugReportButton } from '@fatagnus/convex-feedback/react';
import { api } from './convex/_generated/api';

<BugReportButton
  reporterType="staff"
  reporterId={user.id}
  reporterEmail={user.email}
  reporterName={user.name}
  bugReportApi={{
    create: api.feedback.bugReports.create,
    generateUploadUrl: api.feedback.bugReports.generateUploadUrl,
  }}
  feedbackApi={{
    create: api.feedback.feedback.create,
    generateUploadUrl: api.feedback.feedback.generateUploadUrl,
  }}
  // Enable AI Interview Mode
  enableInterview={true}
  defaultMode="interview" // or "form" to default to manual form
  interviewApi={{
    startBugInterview: api.feedback.agents.feedbackInterviewAgent.startBugInterview,
    startFeedbackInterview: api.feedback.agents.feedbackInterviewAgent.startFeedbackInterview,
    continueInterview: api.feedback.agents.feedbackInterviewAgent.continueInterview,
    getPendingForThread: api.feedback.inputRequests.getPendingForThread,
    getSessionByThread: api.feedback.agents.feedbackInterviewAgent.getSessionByThread,
  }}
/>

Providing Context

You can provide application context to help the AI ask more relevant questions:

<BugReportButton
  // ... other props
  interviewContext={{
    // Application information
    appName: 'Logsign SIEM',
    appDescription: 'A security information and event management platform',
    
    // Feature areas (AI will offer these as choices)
    featureAreas: [
      { name: 'Dashboard', description: 'Main overview and metrics' },
      { name: 'Alerts', description: 'Security alert management' },
      { name: 'Reports', description: 'Analytics and reporting' },
      { name: 'Settings', description: 'User and system configuration' },
    ],
    
    // Known issues (AI will check for duplicates)
    knownIssues: [
      { title: 'Slow dashboard loading', description: 'Dashboard takes 5+ seconds on first load' },
      { title: 'Export timeout', description: 'Large reports fail to export' },
    ],
    
    // Custom questions to ask during interview
    customQuestions: {
      bug: [
        'Are you using any browser extensions?',
        'Did this work before a recent update?',
      ],
      feedback: [
        'How urgent is this for your workflow?',
        'Would a workaround help in the meantime?',
      ],
    },
    
    // Additional instructions for the AI
    additionalInstructions: 'Our users are security professionals, so technical terms are okay.',
  }}
/>

InterviewContext Type

interface InterviewContext {
  /** Application/product name (e.g., "Logsign SIEM") */
  appName?: string;
  
  /** Brief description of what the app does */
  appDescription?: string;
  
  /** Feature areas/modules in the app */
  featureAreas?: Array<{
    name: string;
    description?: string;
  }>;
  
  /** Known issues or FAQ items to help detect duplicates */
  knownIssues?: Array<{
    title: string;
    description?: string;
  }>;
  
  /** Domain-specific questions to include in the interview */
  customQuestions?: {
    bug?: string[];      // Extra questions for bug reports
    feedback?: string[]; // Extra questions for feedback
  };
  
  /** Free-form text for any other context the agent should know */
  additionalInstructions?: string;
}

How It Works

  1. User clicks the bug report button - The modal opens with an "AI Interview Mode" toggle
  2. Interview starts - The AI greets the user and asks what went wrong (for bugs) or what idea they have (for feedback)
  3. Conversational Q&A - The AI asks 3-5 clarifying questions to understand the issue
  4. Report generated - The AI generates a well-structured report with title, description, severity/priority, and reproduction steps
  5. Review and submit - The user can review and edit the generated report before submitting

Interview Input Types

The AI can ask for input in three formats:

  • Text - Open-ended questions (single line or multiline)
  • Choice - Select from predefined options (e.g., feature areas, frequency)
  • Form - Multiple fields at once (rarely used)

Fallback Behavior

  • If OPENROUTER_API_KEY is not configured, interview mode will show an error and users can switch to the form
  • Users can always toggle between "AI Interview" and "Quick Form" modes
  • Screenshots and browser diagnostics are still captured automatically in interview mode

AI Analysis

When OPENROUTER_API_KEY is configured, the component automatically analyzes submissions:

Bug Reports

  • Summary - Concise description of the bug
  • Root Cause Analysis - Potential underlying causes
  • Reproduction Steps - Steps to reproduce the issue
  • Suggested Fix - Recommended approach to resolve
  • Estimated Effort - Low/Medium/High effort estimate
  • Suggested Severity - AI-recommended severity level

Feedback

  • Summary - Concise description of the feedback
  • Impact Analysis - What areas/users are affected
  • Action Items - Concrete next steps
  • Estimated Effort - Low/Medium/High effort estimate
  • Suggested Priority - AI-recommended priority level

Email Notifications

When RESEND_API_KEY is configured, the component sends email notifications:

To Reporters

  • Thank you email with submission summary
  • Professional HTML email template

To Support Teams

  • Full submission details with AI analysis
  • Routed based on feedback type or bug severity
  • Rich HTML template with all diagnostics

Schema

The component creates these tables:

  • bugReports - Bug report submissions
  • feedback - Feedback submissions
  • supportTeams - Team configuration for notification routing
  • feedbackInputRequests - Pending user input requests during AI interviews
  • interviewSessions - Interview state and generated reports
  • ticketCounters - Sequential counters for ticket numbers
  • apiKeys - API keys for REST API authentication

TypeScript Types

import type {
  BugReport,
  Feedback,
  BugSeverity,
  BugStatus,
  FeedbackType,
  FeedbackPriority,
  FeedbackStatus,
  ApiKey,
  ApiKeyCreated,
  PromptTemplate,
  RegisterFeedbackRoutesOptions,
  InterviewContext,
} from '@fatagnus/convex-feedback';

License

Apache-2.0