Skip to content

Conversation

@ReeseAstor
Copy link
Owner

@ReeseAstor ReeseAstor commented Sep 28, 2025

Integrate Supabase, Google Drive, and Notion to enable optional file uploads and credit memo exports, configured via environment variables and controlled by new UI checkboxes.


Open in Cursor Open in Web


Note

Adds optional Supabase Storage, Notion export, and Google Drive upload integrations with UI checkboxes, new API endpoints, and DB fields configured via environment variables.

  • Backend:
    • Integrations layer: New config/integrations.js for Supabase, Notion, and Google Drive clients plus helpers (uploadFileToSupabase, uploadFileToGoogleDrive, exportCreditMemoToNotion).
    • API updates: POST /api/upload-financial accepts uploadToSupabase/uploadToDrive; POST /api/credit-memos accepts exportToNotion; new GET /api/integrations returns availability flags.
    • Runtime: Loads env via dotenv; ensures uploads/ exists.
  • Database:
    • Extend financial_data with supabase_path, supabase_public_url, gdrive_file_id, gdrive_web_view_link.
    • Extend credit_memos with notion_page_id, notion_url.
    • Adds best-effort migration (ensureColumnExists).
  • Frontend:
    • UI checkboxes in public/index.html for Supabase/Drive on upload and Notion on memo.
    • public/script.js: sends flags, parses metrics, and disables checkboxes based on GET /api/integrations.
  • Config/Docs:
    • .env.example with required vars; README.md adds setup for Supabase, Notion, Google Drive and runtime notes.
  • Dependencies:
    • Adds @supabase/supabase-js, @notionhq/client, googleapis, and dotenv (updates package.json/lock).

Written by Cursor Bugbot for commit 865d622. This will update automatically on new commits. Configure here.

Co-authored-by: info <info@reeseastor.com>
@cursor
Copy link

cursor bot commented Sep 28, 2025

Cursor Agent can help with this pull request. Just @cursor in comments and I'll start working on changes in this branch.
Learn more about Cursor Agents

@ReeseAstor ReeseAstor marked this pull request as ready for review September 29, 2025 01:02
Copilot AI review requested due to automatic review settings September 29, 2025 01:02
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Adds optional external service integrations (Supabase Storage, Notion, Google Drive) to the application with configuration via environment variables and UI checkboxes for per-action opt-in functionality.

  • New integration configuration module with service client initialization and availability checking
  • Extended file upload and credit memo APIs to support optional external service uploads/exports
  • Added UI checkboxes and client-side integration availability loading
  • Database schema updates to store external service references

Reviewed Changes

Copilot reviewed 7 out of 8 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
server.js Adds integration imports, database columns, migration logic, and extended APIs
public/script.js Adds integration availability loading and checkbox handling
public/index.html Adds UI checkboxes for Supabase, Drive, and Notion integrations
package.json Updates dependencies to include integration libraries
config/integrations.js New module for service client initialization and helper functions
README.md Adds integration setup documentation
.env.example Adds environment variable template

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Comment on lines +20 to +21
if (googlePrivateKey && googlePrivateKey.includes('\\n')) {
googlePrivateKey = googlePrivateKey.replace(/\\n/g, '\n');
Copy link

Copilot AI Sep 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The private key processing logic should handle all common escape sequences, not just \\n. Consider also handling \\r\\n and other whitespace characters that might be escaped in environment variables.

Suggested change
if (googlePrivateKey && googlePrivateKey.includes('\\n')) {
googlePrivateKey = googlePrivateKey.replace(/\\n/g, '\n');
if (googlePrivateKey) {
// Unescape all common escape sequences (e.g., \n, \r, \t, etc.)
googlePrivateKey = JSON.parse('"' + googlePrivateKey.replace(/\\/g, '\\\\').replace(/"/g, '\\"') + '"');

Copilot uses AI. Check for mistakes.
fileId,
requestBody: { role: 'reader', type: 'anyone' },
});
} catch (e) {}
Copy link

Copilot AI Sep 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The empty catch block silently ignores permission setting failures. Consider logging the error or at least adding a comment explaining why this failure is acceptable.

Suggested change
} catch (e) {}
} catch (e) {
console.error('Failed to set Google Drive file permissions for fileId:', fileId, e);
}

Copilot uses AI. Check for mistakes.
Comment on lines +196 to +199
(async () => {
const updates = {};
const originalName = (req.file.originalname || 'file').replace(/\s+/g, '_');
const destinationPath = `company_${company_id || 'unknown'}/${Date.now()}_${originalName}`;
Copy link

Copilot AI Sep 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The filename sanitization only replaces spaces with underscores but doesn't handle other potentially dangerous characters. Consider using a more comprehensive sanitization approach that removes or escapes characters like ../, special symbols, or unicode characters that could cause path traversal or filesystem issues.

Copilot uses AI. Check for mistakes.
Comment on lines +114 to +116
// Utility to add a column if it does not exist (for existing DBs)
function ensureColumnExists(tableName, columnName, columnType) {
return new Promise((resolve, reject) => {
Copy link

Copilot AI Sep 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Direct string interpolation in SQL queries creates a potential SQL injection vulnerability. Use parameterized queries or validate tableName against a whitelist of allowed table names.

Suggested change
// Utility to add a column if it does not exist (for existing DBs)
function ensureColumnExists(tableName, columnName, columnType) {
return new Promise((resolve, reject) => {
// Utility to add a column if it does not exist (for existing DBs)
// Whitelist of allowed table names for schema changes
const ALLOWED_TABLES = [
'novels',
'chapters',
'story_beats',
'financial_data',
'credit_memos'
];
function ensureColumnExists(tableName, columnName, columnType) {
return new Promise((resolve, reject) => {
if (!ALLOWED_TABLES.includes(tableName)) {
return reject(new Error(`Invalid table name: ${tableName}`));
}

Copilot uses AI. Check for mistakes.
if (err) return reject(err);
const exists = rows.some(r => r.name === columnName);
if (exists) return resolve();
db.run(`ALTER TABLE ${tableName} ADD COLUMN ${columnName} ${columnType}`, (alterErr) => {
Copy link

Copilot AI Sep 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Direct string interpolation in SQL ALTER TABLE statement is unsafe. Validate tableName, columnName, and columnType parameters against whitelists or use a safer approach for schema migrations.

Copilot uses AI. Check for mistakes.
Comment on lines +220 to +230
const setClauses = Object.keys(updates).map(k => `${k} = ?`).join(', ');
const params = [...Object.values(updates), recordId];
db.run(`UPDATE financial_data SET ${setClauses} WHERE id = ?`, params, (updErr) => {
if (updErr) {
console.warn('Failed to update financial_data with external links:', updErr.message);
}
res.json({ id: recordId, message: 'Financial document uploaded and processed', ...updates });
});
} else {
res.json({ id: recordId, message: 'Financial document uploaded and processed' });
}
Copy link

Copilot AI Sep 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Column names from Object.keys(updates) are directly interpolated into SQL without validation. Validate column names against a whitelist to prevent SQL injection through malicious property names.

Copilot uses AI. Check for mistakes.
"license": "MIT",
"dependencies": {
"@notionhq/client": "^5.1.0",
"@supabase/storage-js": "^2.12.2",
Copy link

Copilot AI Sep 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The @supabase/storage-js package is redundant since @supabase/supabase-js already includes storage functionality. Remove this dependency to avoid potential version conflicts and reduce bundle size.

Suggested change
"@supabase/storage-js": "^2.12.2",

Copilot uses AI. Check for mistakes.
Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants