Refactor Slack handler to utilize shared types and remove local schema definitions

This commit is contained in:
dal 2025-07-03 16:23:59 -06:00
parent 3a3836761f
commit f5eb9496c5
No known key found for this signature in database
GPG Key ID: 16F4B0E1E9F61122
5 changed files with 61 additions and 46 deletions

View File

@ -1,56 +1,18 @@
import { getUserOrganizationId } from '@buster/database';
import {
InitiateOAuthSchema,
OAuthCallbackSchema,
SlackError,
SlackErrorCodes,
UpdateIntegrationSchema,
} from '@buster/server-shared/slack';
import { SlackChannelService } from '@buster/slack';
import type { Context } from 'hono';
import { HTTPException } from 'hono/http-exception';
import { z } from 'zod';
import { getActiveIntegration, updateDefaultChannel } from './services/slack-helpers';
import * as slackHelpers from './services/slack-helpers';
import { type SlackOAuthService, createSlackOAuthService } from './services/slack-oauth-service';
// Request schemas
const InitiateOAuthSchema = z.object({
metadata: z
.object({
returnUrl: z.string().optional(),
source: z.string().optional(),
projectId: z.string().uuid().optional(),
})
.optional(),
});
const OAuthCallbackSchema = z.object({
code: z.string(),
state: z.string(),
});
const UpdateIntegrationSchema = z.object({
default_channel: z
.object({
name: z.string().min(1),
id: z.string().min(1),
})
.optional(),
});
// Custom error class
export class SlackError extends Error {
constructor(
message: string,
public statusCode: 500 | 400 | 401 | 403 | 404 | 409 | 429 | 503 = 500,
public code?: string
) {
super(message);
this.name = 'SlackError';
}
toResponse() {
return {
error: this.message,
code: this.code,
};
}
}
export class SlackHandler {
private slackOAuthService: SlackOAuthService | null = null;
private _initializationAttempted = false;

View File

@ -1,7 +1,8 @@
import { Hono } from 'hono';
import { HTTPException } from 'hono/http-exception';
import { requireAuth } from '../../../middleware/auth';
import { SlackError, slackHandler } from './handler';
import { slackHandler } from './handler';
import { SlackError } from '@buster/server-shared/slack';
const app = new Hono()
// Public endpoints (no auth required for OAuth flow)

View File

@ -34,6 +34,10 @@
"./currency": {
"types": "./dist/currency/index.d.ts",
"default": "./dist/currency/index.js"
},
"./slack": {
"types": "./dist/slack/index.d.ts",
"default": "./dist/slack/index.js"
}
},
"dependencies": {

View File

@ -0,0 +1,37 @@
// Custom error class for Slack integration errors
export class SlackError extends Error {
constructor(
message: string,
public statusCode: 500 | 400 | 401 | 403 | 404 | 409 | 429 | 503 = 500,
public code?: string
) {
super(message);
this.name = 'SlackError';
}
toResponse() {
return {
error: this.message,
code: this.code,
};
}
}
// Common error codes
export const SlackErrorCodes = {
INTEGRATION_NOT_CONFIGURED: 'INTEGRATION_NOT_CONFIGURED',
INTEGRATION_DISABLED: 'INTEGRATION_DISABLED',
INTEGRATION_EXISTS: 'INTEGRATION_EXISTS',
INTEGRATION_NOT_FOUND: 'INTEGRATION_NOT_FOUND',
OAUTH_INIT_ERROR: 'OAUTH_INIT_ERROR',
GET_INTEGRATION_ERROR: 'GET_INTEGRATION_ERROR',
REMOVE_INTEGRATION_ERROR: 'REMOVE_INTEGRATION_ERROR',
UPDATE_DEFAULT_CHANNEL_ERROR: 'UPDATE_DEFAULT_CHANNEL_ERROR',
INVALID_REQUEST_BODY: 'INVALID_REQUEST_BODY',
TOKEN_RETRIEVAL_ERROR: 'TOKEN_RETRIEVAL_ERROR',
INVALID_TOKEN: 'INVALID_TOKEN',
RATE_LIMITED: 'RATE_LIMITED',
GET_CHANNELS_ERROR: 'GET_CHANNELS_ERROR',
} as const;
export type SlackErrorCode = (typeof SlackErrorCodes)[keyof typeof SlackErrorCodes];

View File

@ -0,0 +1,11 @@
// Export all request types and schemas
export * from './requests.types';
export type * from './requests.types';
// Export all response types
export * from './responses.types';
export type * from './responses.types';
// Export error types and classes
export * from './errors.types';
export type * from './errors.types';