8000 Development mode by eleanorreem · Pull Request #72 · chaynHQ/tools · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Development mode #72

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

Open
wants to merge 3 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,19 @@ NEXT_PUBLIC_ENV=development
NEXT_PUBLIC_GOOGLE_SITE_VERIFICATION=

# Typeform Feedback URL (optional)
NEXT_PUBLIC_TYPEFORM_FEEDBACK_URL=
TYPEFORM_FEEDBACK_URL=

# Google AI API Key for Gemini
GOOGLE_AI_API_KEY=

# Slack Webhook URL for notifications
SLACK_WEBHOOK_URL=

# Zapier Webhook URL for feedback collection
NEXT_PUBLIC_ZAPIER_FEEDBACK_WEBHOOK_URL=
NEXT_PUBLIC_ZAPIER_FOLLOWUP_WEBHOOK_URL=
NEXT_PUBLIC_ZAPIER_QUALITY_WEBHOOK_URL=
# Zapier Webhook URLs for data collection
ZAPIER_FEEDBACK_WEBHOOK_URL=
ZAPIER_FOLLOWUP_WEBHOOK_URL=
ZAPIER_QUALITY_WEBHOOK_URL=
ZAPIER_DEVELOPMENT_INPUT_COLLECTION_WEBHOOK_URL=

# Zapier Webhook Token for authentication
ZAPIER_WEBHOOK_TOKEN=

ZAPIER_WEBHOOK_TOKEN=
112 changes: 112 additions & 0 deletions app/api/dev-data-collection/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import { handleApiError, serverInstance as rollbar } from '@/lib/rollbar';
import { sendToZapier } from '@/lib/zapier';
import { NextResponse } from 'next/server';

export async function POST(request: Request) {
rollbar.info('dev-data-collection: Received development data submission');

try {
// Only allow in development environment
if (process.env.NEXT_PUBLIC_ENV !== 'development') {
rollbar.warning('dev-data-collection: Attempted to use in non-development environment');
return NextResponse.json(
{ error: 'This endpoint is only available in development' },
{ status: 403 },
);
}

if (!process.env.ZAPIER_DEVELOPMENT_INPUT_COLLECTION_WEBHOOK_URL) {
rollbar.warning('dev-data-collection: Zapier development webhook URL not configured');
return NextResponse.json(
{ error: 'Development webhook URL not configured' },
{ status: 500 },
);
}

const body = await request.json();

// Validate required fields
if (!body.formData || !body.generatedLetter) {
rollbar.error('dev-data-collection: Missing required fields', { body });
return NextResponse.json(
{ error: 'Missing required fields: formData and generatedLetter' },
{ status: 400 },
);
}

// Prepare the payload for Zapier
const zapierPayload = {
timestamp: new Date().toISOString(),
environment: 'development',

// Platform Information
platform_id: body.formData.platformInfo?.platformId || '',
platform_name: body.formData.platformInfo?.platformName || '',
platform_is_custom: body.formData.platformInfo?.isCustom || false,
platform_custom_name: body.formData.platformInfo?.customName || '',

// Reporting Information
reporting_status: body.formData.reportingInfo?.status || '',

// Initial Questions
content_type: body.formData.initialQuestions?.contentType || '',
content_context: body.formData.initialQuestions?.contentContext || '',
content_location_type: body.formData.initialQuestions?.contentLocationType || '',
content_url: body.formData.initialQuestions?.contentUrl || '',
content_description: body.formData.initialQuestions?.contentDescription || '',
image_upload_date: body.formData.initialQuestions?.imageUploadDate || '',
image_taken_date: body.formData.initialQuestions?.imageTakenDate || '',
ownership_evidence: body.formData.initialQuestions?.ownershipEvidence || '',
impact_statement: body.formData.initialQuestions?.impactStatement || '',

// Reporting Details
standard_process_details: body.formData.reportingDetails?.standardProcessDetails || '',
escalated_process_details: body.formData.reportingDetails?.escalatedProcessDetails || '',
response_received: body.formData.reportingDetails?.responseReceived || '',
additional_steps_taken: body.formData.reportingDetails?.additionalStepsTaken || '',

// Follow-up Data
follow_up_questions_count: body.formData.followUpData?.questions?.length || 0,
follow_up_answers: JSON.stringify(body.formData.followUpData?.answers || {}),

// Generated Letter
letter_subject: body.generatedLetter?.subject || '',
letter_body: body.generatedLetter?.body || '',
letter_next_steps: JSON.stringify(body.generatedLetter?.nextSteps || []),

// Additional metadata
session_id: body.sessionId || '',
user_agent: request.headers.get('user-agent') || '',
completion_time_seconds: body.completionTimeSeconds || 0,
};

await sendToZapier(process.env.ZAPIER_DEVELOPMENT_INPUT_COLLECTION_WEBHOOK_URL, zapierPayload);

rollbar.info('dev-data-collection: Successfully sent development data to Zapier', {
platform: zapierPayload.platform_name,
contentType: zapierPayload.content_type,
hasFollowUp: zapierPayload.follow_up_questions_count > 0,
});

return NextResponse.json({ success: true });
} catch (error: any) {
const { error: errorMessage, status } = handleApiError(error, '/api/dev-data-collection');
rollbar.error('dev-data-collection: Error processing development data submission', {
error: errorMessage,
status,
stack: error.stack,
});
return NextResponse.json({ error: errorMessage }, { status });
}
}

export async function OPTIONS() {
return new NextResponse(null, {
status: 200,
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'POST, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type',
},
});
}
6 changes: 3 additions & 3 deletions app/api/feedback/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ import { NextResponse } from 'next/server';
export async function POST(request: Request) {
rollbar.info('feedback: Received feedback submission');
try {
if (!process.env.NEXT_PUBLIC_ZAPIER_FEEDBACK_WEBHOOK_URL) {
if (!process.env.ZAPIER_FEEDBACK_WEBHOOK_URL) {
return NextResponse.json({ error: 'Zapier webhook URL not configured' }, { status: 500 });
}

const body = await request.json();
await sendToZapier(process.env.NEXT_PUBLIC_ZAPIER_FEEDBACK_WEBHOOK_URL, body);
await sendToZapier(process.env.ZAPIER_FEEDBACK_WEBHOOK_URL, body);

return NextResponse.json({ success: true });
} catch (error: any) {
Expand All @@ -33,4 +33,4 @@ export async function OPTIONS() {
'Access-Control-Allow-Headers': 'Content-Type',
},
});
}
}
6 changes: 3 additions & 3 deletions app/api/follow-up-questions/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export async function POST(request: Request) {
});

// Send questions to Zapier if webhook URL is configured
if (process.env.NEXT_PUBLIC_ZAPIER_FOLLOWUP_WEBHOOK_URL) {
if (process.env.ZAPIER_FOLLOWUP_WEBHOOK_URL) {
const zapierPayload = {
date: new Date().toISOString(),
Q1: questions[0]?.question || '',
Expand All @@ -57,7 +57,7 @@ export async function POST(request: Request) {
Q6: questions[5]?.question || '',
};

await sendToZapier(process.env.NEXT_PUBLIC_ZAPIER_FOLLOWUP_WEBHOOK_URL, zapierPayload);
await sendToZapier(process.env.ZAPIER_FOLLOWUP_WEBHOOK_URL, zapierPayload);
}

return NextResponse.json(questions);
Expand All @@ -73,4 +73,4 @@ export async function POST(request: Request) {

return NextResponse.json({ error: errorMessage }, { status });
}
}
}
6 changes: 3 additions & 3 deletions app/api/quality-check-letter/route.ts
Expand Up
Original file line number Diff line number Diff line change
@@ -51,8 +51,8 @@ export async function POST(request: Request) {
const qualityCheckResult = await retryWithDelay(generateQualityCheck);

// Send critical issues to Zapier if webhook URL is configured
// if (qualityCheckResult.severity === 'critical' && process.env.NEXT_PUBLIC_ZAPIER_QUALITY_WEBHOOK_URL) {
if (process.env.NEXT_PUBLIC_ZAPIER_QUALITY_WEBHOOK_URL) {
// if (qualityCheckResult.severity === 'critical' && process.env.ZAPIER_QUALITY_WEBHOOK_URL) {
if (process.env.ZAPIER_QUALITY_WEBHOOK_URL) {
const zapierPayload = {
date: new Date().toISOString(),
issue1: qualityCheckResult.issues[0]
Expand All @@ -75,7 +75,7 @@ export async function POST(request: Request) {
: '',
};

await sendToZapier(process.env.NEXT_PUBLIC_ZAPIER_QUALITY_WEBHOOK_URL, zapierPayload);
await sendToZapier(process.env.ZAPIER_QUALITY_WEBHOOK_URL, zapierPayload);
}

rollbar.info('QualityCheckLetter: Successfully parsed quality check result', {
Expand Down
10 changes: 5 additions & 5 deletions app/client-layout.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"use client";
'use client';

import { DevelopmentWarning } from '@/components/dev/development-warning';
import { DisclaimerBanner } from '@/components/feedback/disclaimer-banner';
import { Footer } from '@/components/layout/footer';
import { Header } from '@/components/layout/header';
Expand All @@ -10,6 +11,7 @@ import { ReactNode } from 'react';
export function ClientLayout({ children }: { children: ReactNode }) {
return (
<FormProvider>
<DevelopmentWarning />
<Header />
<main className="flex-1">
<div className="max-w-7xl mx-auto px-4 sm:px-6 py-4 sm:py-6 min-h-[calc(100vh-4rem)]">
Expand All @@ -18,9 +20,7 @@ export function ClientLayout({ children }: { children: ReactNode }) {
</div>
</main>
<Footer />
<GoogleAnalytics
gaId={process.env.NEXT_PUBLIC_GA_ID || ''}
/>
<GoogleAnalytics gaId={process.env.NEXT_PUBLIC_GA_ID || ''} />
</FormProvider>
);
}
}
Loading
0