# 🚀 Welcome to Your Defensify IP Platform

Congratulations on purchasing the **Defensify IP Business-in-a-Box**. You now have a complete, self-hostable pipeline for defensive patenting and prior art publication, ready to brand and deploy as your own.

## 📦 What's in the Box?
Your package includes:
- **Custom Branding:** Your logo and color scheme integrated into the frontend.
- **Dynamic Pricing Engine:** Complexity-based attorney fee calculator.
- **Prior Art PDF Generator:** Automated technical disclosure formatting.
- **Secure Backend:** Serverless functions ready for payment and submission handling.
- **Admin Dashboard:** A password-protected panel to review, approve, and publish submissions.

---

## 🛠️ Quick Start Deployment

This platform is designed to run on **Netlify**, but the backend functions are portable to most serverless hosts. To go live:

### 1. Repository Setup
- Create a new private repository on GitHub/GitLab/Bitbucket.
- Push this codebase to your repository.

### 2. Connect to a Hosting Provider
- Log in to your Netlify account (or equivalent) and choose **"Add new site" > "Import an existing project"**.
- Select your repository and deploy.

### 3. Choose Your Backend Options
This platform supports more than one configuration for each core service, so you can match it to your own infrastructure or budget.

#### Database — pick one
| Option | Best for | `DATABASE_TYPE` |
| :--- | :--- | :--- |
| **Turso (LibSQL)** | Lightweight, low-cost, edge-friendly | `turso` |
| **PostgreSQL** (Neon, Supabase, AWS RDS, or any standard Postgres host) | Larger teams, existing Postgres infrastructure | `postgres` |

#### File / Document Delivery — pick one or combine
| Option | Description |
| :--- | :--- |
| **Direct email attachment** | Generated PDFs/certificates are attached directly to the confirmation email via SMTP. Simplest option, no extra storage account needed. |
| **Cloud storage + link** | Files are uploaded to your own object storage (e.g. S3-compatible bucket, Google Cloud Storage, or similar) and a download link is emailed instead. Better for larger files or long-term retention. |

#### Payment Processor — pick one or offer both
| Option | Description |
| :--- | :--- |
| **PayPal** | Buyer-side PayPal Checkout buttons, good for broad consumer trust. |
| **Stripe** | Card-based Stripe Checkout, good for a more traditional checkout flow and subscription billing if you add tiers later. |

### 4. Configure Environment Variables
In your hosting dashboard (e.g. `Site Settings > Environment Variables`), add the variables for whichever options you chose above:

#### **A. Database (Required — choose matching set)**
| Variable | Example | Description |
| :--- | :--- | :--- |
| `DATABASE_TYPE` | `turso` or `postgres` | Selects the active database adapter. |
| `DATABASE_URL` | `libsql://...` or `postgresql://...` | Connection string for your chosen database. |
| `TURSO_AUTH_TOKEN` | `[Your-Token]` | Required only if `DATABASE_TYPE=turso`. |

#### **B. Payments (Required for revenue — configure at least one)**
| Variable | Description |
| :--- | :--- |
| `PAYPAL_CLIENT_ID` | Your PayPal REST API Client ID. |
| `PAYPAL_SECRET` | Your PayPal REST API Secret. |
| `STRIPE_SECRET_KEY` | Your Stripe secret key, if offering card payments. |
| `STRIPE_PUBLISHABLE_KEY` | Your Stripe publishable key. |

#### **C. Email & File Delivery (Required)**
| Variable | Description |
| :--- | :--- |
| `SMTP_HOST` | SMTP host for any transactional email provider (Postmark, SendGrid, Mailgun, your own mail server, etc). |
| `SMTP_PORT` | Usually `587` (STARTTLS) or `465` (SSL). |
| `SMTP_USER` | SMTP username or API token. |
| `SMTP_PASS` | SMTP password or API token. |
| `EMAIL_FROM` | Verified sender address shown to customers. |
| `ADMIN_EMAIL` | **Required — see note below.** Support email shown on-site and on generated certificates, and the address that receives payment alerts. |
| `STORAGE_BUCKET_URL` | Only needed if using the cloud storage delivery option above. |

> ⚠️ **You must set `ADMIN_EMAIL`.** When a customer's payment for a defensive patent submission completes — whether through the Stripe or PayPal checkout flow — the matching webhook function (`stripe-webhook` or `paypal-webhook`) sends a payment-confirmation alert to `ADMIN_EMAIL` through your configured SMTP provider. This is how you, the operator, learn that a new paid submission is waiting in the Admin Dashboard to be reviewed and published. If `ADMIN_EMAIL` is left unset or wrong, you'll have no way of knowing a submission was paid for short of manually checking the dashboard.

#### **D. Admin Access (Required)**
| Variable | Description |
| :--- | :--- |
| `ADMIN_PASSWORD` | Password for your admin dashboard. Choose something strong; this gates submission review and publishing. |

#### **E. IPFS Certificate Storage — Pinata (Required for blockchain-enabled certificates)**
| Variable | Description |
| :--- | :--- |
| `PINATA_API_KEY` | Your Pinata API key. |
| `PINATA_API_SECRET` | Your Pinata API secret. |

> **Getting Pinata credentials:** Sign up at `https://app.pinata.cloud` → **API Keys** → **New Key** → enable **pinFileToIPFS** → copy the key and secret (shown once only). Pinata's free tier covers up to 1 GB of pinned storage. Once configured, published disclosure certificates are permanently pinned to IPFS and recipients receive a tamper-evident IPFS gateway link via Postmark. The CID (Content Identifier) is also stored in the database so it can be independently verified.

### 5. Connect Your Payment Webhooks
Whichever processor(s) you enabled in Step 3, you'll need to register a webhook so the platform knows when a payment completes:

**PayPal**
1. In the [PayPal Developer Dashboard](https://developer.paypal.com/dashboard/applications), open your REST API app → **Webhooks** tab → **Add Webhook**.
2. Webhook URL: `https://<your-domain>/.netlify/functions/paypal-webhook`
3. Subscribe to at minimum: `CHECKOUT.ORDER.APPROVED`, `CHECKOUT.ORDER.COMPLETED`, `CHECKOUT.ORDER.DECLINED`, `CHECKOUT.ORDER.VOIDED`.
4. Save, then copy the generated Webhook ID into `PAYPAL_WEBHOOK_ID`.

**Stripe**
1. In the [Stripe Dashboard](https://dashboard.stripe.com) → **Developers > Webhooks > Add endpoint**.
2. Endpoint URL: `https://<your-domain>/.netlify/functions/stripe-webhook`
3. Subscribe to at minimum: `checkout.session.completed`, `checkout.session.expired`, `payment_intent.payment_failed`.
4. Save, then copy the Signing secret into `STRIPE_WEBHOOK_SECRET`.

Either webhook, once firing correctly, will move a submission's status to `'paid'` and send the alert email described in Step 4 above — that's your cue to log into the admin dashboard and publish it.

### 6. Create the Database Schema
Before the platform can accept submissions, you must create the required table in your database. Run the following SQL once in your database provider's SQL console (e.g. Neon's SQL Editor at `console.neon.tech`, or equivalent for your chosen provider):

```sql
-- Core submissions table
CREATE TABLE IF NOT EXISTS submissions (
  id                TEXT PRIMARY KEY DEFAULT gen_random_uuid()::text,
  title             TEXT NOT NULL,
  author            TEXT,
  email             TEXT,
  claims            TEXT,
  background        TEXT,
  plan              TEXT DEFAULT 'basic',
  estimated_fee     NUMERIC(10, 2),
  status            TEXT DEFAULT 'submitted',
  paypal_order_id   TEXT,
  stripe_session_id TEXT,
  payment_method    TEXT,
  amount_paid       NUMERIC(10, 2),
  pdf_url           TEXT,
  html_url          TEXT,
  certificate_url   TEXT,
  microsite_url     TEXT,
  google_site_url   TEXT,
  indexed_at        TIMESTAMPTZ,
  published_at      TIMESTAMPTZ,
  created_at        TIMESTAMPTZ DEFAULT now(),
  updated_at        TIMESTAMPTZ DEFAULT now(),
  attachment_count  INTEGER DEFAULT 0,
  attachments       JSONB DEFAULT '[]',
  metadata          JSONB DEFAULT '{}'
);

CREATE INDEX IF NOT EXISTS idx_submissions_status
  ON submissions (status);

CREATE INDEX IF NOT EXISTS idx_submissions_created_at
  ON submissions (created_at DESC);

CREATE INDEX IF NOT EXISTS idx_submissions_paypal_order
  ON submissions (paypal_order_id)
  WHERE paypal_order_id IS NOT NULL;

CREATE INDEX IF NOT EXISTS idx_submissions_stripe_session
  ON submissions (stripe_session_id)
  WHERE stripe_session_id IS NOT NULL;

CREATE OR REPLACE FUNCTION update_updated_at()
RETURNS TRIGGER AS $$
BEGIN
  NEW.updated_at = now();
  RETURN NEW;
END;
$$ LANGUAGE plpgsql;

DROP TRIGGER IF EXISTS set_updated_at ON submissions;
CREATE TRIGGER set_updated_at
  BEFORE UPDATE ON submissions
  FOR EACH ROW
  EXECUTE FUNCTION update_updated_at();
```

This is safe to run more than once — all statements use `IF NOT EXISTS` and `CREATE OR REPLACE`. Once run, the admin dashboard should display "No submissions yet" confirming the connection and schema are both working.

### 7. How a Submission Moves Through the System
```
Customer submits form → record created (status: 'submitted')
                       → PayPal or Stripe checkout
                       → webhook confirms payment → status: 'paid' → alert emailed to ADMIN_EMAIL
                       → you review & click PUBLISH in the Admin Dashboard
                       → PDF + HTML + certificate generated
                       → status: 'published'
```

---

## 🔐 Licensing & Restrictions
- **Your Mode:** `white_label`. This instance sells **Basic** and **Premium** publication tiers to your own clients.
- **Restrictions:** The original "$5,000 Enterprise" resale tier is disabled in this build to preserve the exclusivity of the Defensify IP platform itself — you're licensed to run the publishing service, not to resell the platform.
- **Customization:** You have full source code access to rebrand, restyle, or extend the platform for your business.

---

## 📞 Support
For technical issues regarding the core engine, contact **AV Associates LLC** at support@jurissource.com.

*Happy Defending!*

---
*This guide ships inside the `web/` folder of your purchased package and is automatically bundled into every $5,000 White Label sale by `functions/package_whitelabel.py`. The operator-only Super Admin Guide is also included in your package, but as a password-protected file inside the archive — it requires a separate credential from your own `ADMIN_PASSWORD`. If you don't already have it, contact **admin@conextwork.com** to request access. It documents internal configuration patterns (database, email, payment webhook setup) that go beyond what's covered here, should you want a deeper reference once you're up and running.*
