← back to AbramsEgo

lib/spend-reviews/config.js

74 lines

'use strict';
/**
 * Spend → Reviews — module config + HARD RAILS.
 *
 * Every post-a-review / send-an-email action is HARD-GATED. The flags below are
 * FALSE by default and NOTHING in this repo flips them; the only way an executor
 * fires for real is a per-item approve click PLUS an explicit live confirm token
 * at call time. Bulk/autonomous execution is never wired — it drafts a memo to
 * the pending-approval queue instead. See executors.js.
 */
const path = require('path');
const os = require('os');

const DATA_DIR = path.join(__dirname, '..', '..', 'data');

module.exports = {
  DATA_DIR,
  // append-only stores
  ITEMS_FILE: path.join(DATA_DIR, 'spend-items.jsonl'),
  PLACE_CACHE: path.join(DATA_DIR, 'merchant-place-cache.jsonl'),
  ACTIONS_LOG: path.join(DATA_DIR, 'spend-review-actions.jsonl'),
  CSV_DROP_DIR: path.join(DATA_DIR, 'csv-drop'),

  // George email bridge (local Mac2) — POST {to,subject,body}, Basic auth.
  GEORGE_URL: process.env.GEORGE_URL || 'http://127.0.0.1:9850',
  GEORGE_AUTH: 'Basic ' + Buffer.from(
    `${process.env.GEORGE_USER || 'admin'}:${process.env.GEORGE_PASS || 'DWSecure2024!'}`
  ).toString('base64'),
  // Default seller-email FROM is Steve's office; overridable.
  DEFAULT_FROM: process.env.SPEND_REVIEW_FROM || 'steve@designerwallcoverings.com',

  // openclaw real-Chrome CLI (drives the Amazon scrape + Google/Amazon review posts).
  OPENCLAW_BIN: process.env.OPENCLAW_BIN || 'openclaw',

  // ---- HARD RAILS (all OFF by default; nothing here flips them) --------------
  // Google Places API is an OPTIONAL, GATED, off-by-default spend fallback. The
  // DTD verdict (Option B) is a $0 no-key resolver; Places only turns on if Steve
  // sets BOTH the key and the enable flag, and even then it obeys a hard cap.
  PLACES_API_ENABLED: process.env.PLACES_API_ENABLED === '1',
  PLACES_API_KEY: process.env.GOOGLE_PLACES_API_KEY || '',
  PLACES_MAX_LOOKUPS_PER_RUN: Number(process.env.PLACES_MAX_LOOKUPS_PER_RUN || 25),
  PLACES_COST_PER_LOOKUP_USD: 0.017, // Find Place SKU, for the cost line

  // Live-fire switch for the executors. Even when true, an executor STILL requires
  // the item's target to be per-item approved AND a matching confirm token. This
  // flag being false means every executor returns its plan (gated) and fires nothing.
  EXECUTORS_LIVE: process.env.SPEND_REVIEW_EXECUTORS_LIVE === '1',

  PENDING_APPROVAL_DIR: path.join(os.homedir(), '.claude', 'yolo-queue', 'pending-approval'),

  SOURCES: ['amazon', 'gmail', 'csv'],
  TARGETS: ['google_review', 'amazon_review', 'seller_email'],

  // Merchants to AUTO-SKIP at ingest: Steve's OWN businesses (a review of your own
  // company is a prohibited fake review) + pure infra/SaaS vendors that aren't the
  // consumer "businesses I spend money on" this feature is for. Matched as
  // normalized substrings (case-insensitive). Extend/replace via the comma-sep
  // env SPEND_REVIEW_EXCLUDE. NOTE: never add bare 'amazon' — Amazon.com purchases
  // are the core use case; the normalizer already strips the amazon/amzn prefix.
  EXCLUDE_MERCHANTS: (process.env.SPEND_REVIEW_EXCLUDE
    ? process.env.SPEND_REVIEW_EXCLUDE.split(',')
    : [
        // Steve's own businesses / brands (self-review = prohibited)
        'designerwallcoverings', 'designer wallcoverings', 'novasuede', 'philipperomano',
        'phillipe romano', 'wallpapersback', "wallpaper's back", 'apartmentwallpaper',
        'agentabrams', 'abrams ego', 'abramsego',
        // pure infra / SaaS vendors (not consumer businesses to review)
        'kamatera', 'cloudflare', 'godaddy', 'namecheap', 'porkbun', 'openai', 'anthropic',
        'replicate', 'elevenlabs', 'twilio', 'stripe', 'purelymail', 'browserbase',
        'moonshot', 'vercel', 'github', 'google workspace', 'google cloud', 'aws',
        'digitalocean', 'linode',
      ]).map((s) => s.trim().toLowerCase()).filter(Boolean),
};