Skip to content
Merged
Show file tree
Hide file tree
Changes from 35 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
1430e44
(feat): created marketing pipeline with basic functionality (generati…
rafchen Feb 26, 2026
b3e717b
updated logos for companies in marketing pipeline
rafchen Feb 28, 2026
0f37b85
updated ui of marketing pipleine to match the rest of the platform
rafchen Feb 28, 2026
a15336e
add company metadata generation pipeline from document upload
ezhu15 Feb 28, 2026
552d44f
refine marketing pipeline generator prompt for B2B context and clarity
mariam-hedgie Feb 28, 2026
8082a38
feat: add platform-specific formatting templates and trend reference …
mariam-hedgie Feb 28, 2026
d74be2f
feat: add .env.example file and enhance marketing pipeline with trend…
mariam-hedgie Mar 1, 2026
490ad66
Added script to display company metadata in terminal
Mar 2, 2026
9bbe796
Added UI page that allows one to view the metadata for their company
Mar 2, 2026
57caeda
feat(marketing-pipeline): implement multi-platform trend research wit…
JunzheShi0702 Mar 2, 2026
9f3ee99
redesigned frontend page
Deodat-Lawson Mar 2, 2026
bcb7294
Adding page to view company metadata from employer home and fixing bugs
Mar 2, 2026
8f5de8e
fix: use supported @vercel/blob version
EricLiu2795 Mar 2, 2026
b623d37
feat(storage): integrate Vercel Blob (Issue #209)
EricLiu2795 Mar 2, 2026
e099a65
(fix): bugfix + fixed icon popping off the screen
rafchen Mar 3, 2026
3a9f826
finished company meta data database design, wrote JSON storage file
c9zA Mar 3, 2026
04ea937
Changed chunks per batch to make extraction faster
Mar 3, 2026
7d0a045
Merging anthonys branch ant/feature/company-metadata-database into mi…
Mar 3, 2026
ea060b3
Fixed errors from merge so that build passes for PR
Mar 3, 2026
c900d40
feat(marketing): add search provider abstraction and trend-search int…
rafchen Mar 4, 2026
38a8141
Promopt imporvement and theme rewrites
Deodat-Lawson Mar 4, 2026
e1c7767
Merge pull request #231 from Deodat-Lawson/feature/marketing-pipeline
Deodat-Lawson Mar 4, 2026
c798daa
Merge branch 'main' into feature/metadata-display
Deodat-Lawson Mar 4, 2026
8d92556
Merge pull request #230 from Deodat-Lawson/feature/metadata-display
Deodat-Lawson Mar 4, 2026
d4a4ef2
Merge branch 'main' into feat/vercel-deploy
Deodat-Lawson Mar 4, 2026
2c576a3
Merge branch 'main' into feat/vercel-deploy
Deodat-Lawson Mar 4, 2026
2658fdf
allows uploading for private blobs
Deodat-Lawson Mar 4, 2026
3fd03a6
update readme for vercel blob logic
Deodat-Lawson Mar 4, 2026
a0f1c96
Merge pull request #227 from Deodat-Lawson/feat/vercel-deploy
Deodat-Lawson Mar 4, 2026
9c5b380
Merge branch 'main' into feature/front-page-improvement
Deodat-Lawson Mar 4, 2026
0ec2b76
improved UI design with new elements
Deodat-Lawson Mar 4, 2026
2b464f1
updated deployment page
Deodat-Lawson Mar 5, 2026
56d856d
fixed vercel deployment
Deodat-Lawson Mar 5, 2026
07c20bc
Merge pull request #234 from Deodat-Lawson/feature/front-page-improve…
Deodat-Lawson Mar 5, 2026
5e3bdf3
Merge branch 'stable' into main
Deodat-Lawson Mar 5, 2026
7f624c4
modified PDA with better results and working
Deodat-Lawson Mar 5, 2026
6a7954b
Merge pull request #237 from Deodat-Lawson/feature/predictive-documen…
Deodat-Lawson Mar 5, 2026
17d829a
fix test
Deodat-Lawson Mar 5, 2026
308063d
Merge pull request #238 from Deodat-Lawson/feature/predictive-documen…
Deodat-Lawson Mar 5, 2026
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
47 changes: 47 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Since the ".env" file is gitignored, you can use the ".env.example" file to
# build a new ".env" file when you clone the repo. Keep this file up-to-date
# when you add new variables to `.env`.

# This file will be committed to version control, so make sure not to have any
# secrets in it. If you are cloning this repo, create a copy of this file named
# ".env" and populate it with your secrets.

# When adding additional environment variables, the schema in "/src/env.js"
# should be updated accordingly.

# Database
DATABASE_URL=""

# Docker Compose: password for PostgreSQL (used by db service)
# POSTGRES_PASSWORD=password

# Clerk Authentication (get from https://clerk.com/)

NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=
CLERK_SECRET_KEY=

# OpenAI API (get from https://platform.openai.com/)

OPENAI_API_KEY=

# UploadThing (get from https://uploadthing.com/)
UPLOADTHING_SECRET="your_uploadthing_secret"
UPLOADTHING_APP_ID="your_uploadthing_app_id"

# Datalab OCR API (optional - get from https://www.datalab.to/)
# Required only if you want to enable OCR processing for scanned documents
DATALAB_API_KEY="your_datalab_api_key"

# Landing.AI OCR API (optional - get from https://www.landing.ai/)
LANDING_AI_API_KEY="your_landing_ai_api_key"

# Tavily API (optional - get from https://www.tavily.com/)
TAVILY_API_KEY="your_tavily_api_key"

# Azure Document Intelligence OCR API (optional - get from https://learn.microsoft.com/en-us/azure/applied-ai-services/document-intelligence/quickstarts/get-started-with-rest-api?pivots=programming-language-rest-api)
AZURE_DOC_INTELLIGENCE_ENDPOINT="your_azure_doc_intelligence_endpoint"
AZURE_DOC_INTELLIGENCE_KEY="your_azure_doc_intelligence_key"

# Inngest (required for background document processing - https://inngest.com/)
INNGEST_EVENT_KEY="dev_placeholder"
INNGEST_SIGNING_KEY="signkey-dev-xxxxx"
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ Create `.env` from `.env.example` and fill required values:
- `DATABASE_URL`
- `NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY`
- `CLERK_SECRET_KEY`
- `BLOB_READ_WRITE_TOKEN` (Vercel Blob read/write token)
- `OPENAI_API_KEY`
- `INNGEST_EVENT_KEY`, as placeholder

Expand All @@ -137,6 +138,18 @@ Optional integrations:
- `LANGCHAIN_TRACING_V2`, `LANGCHAIN_API_KEY`, `LANGCHAIN_PROJECT`
- `DEBUG_PERF` (`1` or `true`) to enable dev perf logs for middleware and key auth/dashboard APIs

### 2.1) Configure Vercel Blob Storage

Vercel Blob is used for storing uploaded documents. Both **public** and **private** stores are supported -- the upload logic auto-detects which mode the store uses and adapts automatically.

1. In the Vercel dashboard, go to **Storage → Blob → Create Store**.
2. Choose either **Public** or **Private** access. Both work:
- **Public** stores produce URLs the browser can load directly (faster for previews).
- **Private** stores keep files behind authentication; the app proxies content through `/api/documents/[id]/content` and `/api/files/[id]` so previews still work.
3. Generate a **Read/Write token** for the store and add it as `BLOB_READ_WRITE_TOKEN` in your environment (`.env` locally, or Vercel Project Settings for deploys).
4. Redeploy so the token is available at build and runtime.
5. Verify: sign in to the Employer Upload page, upload a small PDF, and confirm `/api/upload-local` returns a `vercel-storage.com` URL without errors.

### 3) Start database and apply schema

```bash
Expand Down
Binary file added dev-output.log
Binary file not shown.
11 changes: 9 additions & 2 deletions docs/deployment.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ docker compose --env-file .env --profile dev up

1. Import repository into Vercel.
2. Configure managed PostgreSQL (Vercel Postgres, Neon, Supabase, etc.).
3. Set `DATABASE_URL` and app environment variables.
3. Set `DATABASE_URL`, `BLOB_READ_WRITE_TOKEN`, and the other app environment variables.
4. Deploy with Vercel defaults.
5. Apply schema once:

Expand All @@ -65,6 +65,12 @@ Optional integrations:
- LangSmith for tracing
- Sidecar (deploy separately and set `SIDECAR_URL`)

### Verifying Blob uploads on Vercel

1. After deploy, sign in to the Employer portal and open `/employer/upload`.
2. Upload any small PDF or DOCX. The `/api/upload-local` response should return a `vercel-storage.com` URL.
3. Paste that URL into a new tab. The file should download directly, confirming Blob access end to end.

## Option 3: VPS self-hosted (Node + reverse proxy)

1. Install Node.js 18+, pnpm, Nginx, and PostgreSQL with pgvector.
Expand All @@ -89,7 +95,8 @@ Optional: Run the sidecar separately and point `SIDECAR_URL` to it.
| `CLERK_SECRET_KEY` | Yes | Clerk secret key |
| `OPENAI_API_KEY` | Yes | OpenAI API key |
| `INNGEST_EVENT_KEY` | Yes (prod) | Inngest event key for background jobs |
| `UPLOADTHING_TOKEN` | Optional | UploadThing for cloud storage |
| `BLOB_READ_WRITE_TOKEN` | Yes (Vercel) | Required for Vercel Blob uploads |
| `UPLOADTHING_TOKEN` | Optional | UploadThing legacy uploader |
| `SIDECAR_URL` | Optional | Sidecar URL for reranking and Graph RAG |
| `TAVILY_API_KEY` | Optional | Web search for analysis |
| `AZURE_DOC_INTELLIGENCE_*` | Optional | OCR for scanned PDFs |
Expand Down
39 changes: 39 additions & 0 deletions drizzle/0002_company_metadata.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
-- Company Metadata Tables
-- One canonical JSON row per company + append-only audit history.

CREATE TABLE IF NOT EXISTS "company_metadata" (
"id" serial PRIMARY KEY NOT NULL,
"company_id" bigint NOT NULL REFERENCES "company"("id") ON DELETE CASCADE,
"schema_version" varchar(20) NOT NULL DEFAULT '1.0.0',
"metadata" jsonb NOT NULL,
"last_extraction_document_id" bigint REFERENCES "document"("id") ON DELETE SET NULL,
"created_at" timestamptz NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" timestamptz
);

CREATE UNIQUE INDEX IF NOT EXISTS "company_metadata_company_id_unique"
ON "company_metadata" ("company_id");

-- ============================================================================

CREATE TABLE IF NOT EXISTS "company_metadata_history" (
"id" serial PRIMARY KEY NOT NULL,
"company_id" bigint NOT NULL REFERENCES "company"("id") ON DELETE CASCADE,
"document_id" bigint REFERENCES "document"("id") ON DELETE SET NULL,
"change_type" varchar(32) NOT NULL, -- extraction | merge | manual_override | deprecation
"diff" jsonb NOT NULL,
"changed_by" varchar(256) NOT NULL,
"created_at" timestamptz NOT NULL DEFAULT CURRENT_TIMESTAMP
);

CREATE INDEX IF NOT EXISTS "company_metadata_history_company_id_idx"
ON "company_metadata_history" ("company_id");

CREATE INDEX IF NOT EXISTS "company_metadata_history_document_id_idx"
ON "company_metadata_history" ("document_id");

CREATE INDEX IF NOT EXISTS "company_metadata_history_created_at_idx"
ON "company_metadata_history" ("created_at");

CREATE INDEX IF NOT EXISTS "company_metadata_history_change_type_idx"
ON "company_metadata_history" ("change_type");
8 changes: 8 additions & 0 deletions drizzle/0002_vercel_blob.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
ALTER TABLE "file_uploads"
ADD COLUMN IF NOT EXISTS "storage_provider" varchar(64) NOT NULL DEFAULT 'database',
ADD COLUMN IF NOT EXISTS "storage_url" varchar(1024),
ADD COLUMN IF NOT EXISTS "storage_pathname" varchar(1024),
ADD COLUMN IF NOT EXISTS "blob_checksum" varchar(128);

ALTER TABLE "file_uploads"
ALTER COLUMN "file_data" DROP NOT NULL;
4 changes: 4 additions & 0 deletions drizzle/0003_company_onboarding.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
-- Add onboarding profile columns to company table
ALTER TABLE "company"
ADD COLUMN IF NOT EXISTS "description" text,
ADD COLUMN IF NOT EXISTS "industry" varchar(256);
3 changes: 3 additions & 0 deletions next.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,9 @@ const config: NextConfig = {
"@img/sharp-libvips-linuxmusl-x64",
"@img/sharp-libvips-linux-x64",
"pdf-lib",
"jszip",
"readable-stream",
"mammoth",
],
};

Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
"@tiptap/starter-kit": "^3.20.0",
"@uploadthing/react": "^7.3.3",
"@vercel/analytics": "^1.6.1",
"@vercel/blob": "^2.3.0",
"cheerio": "^1.2.0",
"class-variance-authority": "^0.7.1",
"clsx": "*",
Expand Down
45 changes: 45 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file added public/images/reddit-snoo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
57 changes: 57 additions & 0 deletions scripts/create-metadata-tables.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import "dotenv/config";
import { db } from "../src/server/db";
import { sql } from "drizzle-orm";

async function createTables() {
try {
console.log("Creating company_metadata table...");

// Create company_metadata table
await db.execute(sql`
CREATE TABLE IF NOT EXISTS pdr_ai_v2_company_metadata (
id SERIAL PRIMARY KEY,
company_id BIGINT NOT NULL REFERENCES pdr_ai_v2_company(id) ON DELETE CASCADE,
schema_version VARCHAR(20) NOT NULL DEFAULT '1.0.0',
metadata JSONB NOT NULL,
last_extraction_document_id BIGINT REFERENCES pdr_ai_v2_document(id) ON DELETE SET NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMPTZ
)
`);

// Create unique index on company_id
await db.execute(sql`
CREATE UNIQUE INDEX IF NOT EXISTS company_metadata_company_id_unique
ON pdr_ai_v2_company_metadata(company_id)
`);

console.log("Creating company_metadata_history table...");

// Create company_metadata_history table
await db.execute(sql`
CREATE TABLE IF NOT EXISTS pdr_ai_v2_company_metadata_history (
id SERIAL PRIMARY KEY,
company_id BIGINT NOT NULL REFERENCES pdr_ai_v2_company(id) ON DELETE CASCADE,
document_id BIGINT REFERENCES pdr_ai_v2_document(id) ON DELETE SET NULL,
change_type VARCHAR(32) NOT NULL,
diff JSONB NOT NULL,
changed_by VARCHAR(256) NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP
)
`);

// Create indexes for history table
await db.execute(sql`CREATE INDEX IF NOT EXISTS company_metadata_history_company_id_idx ON pdr_ai_v2_company_metadata_history(company_id)`);
await db.execute(sql`CREATE INDEX IF NOT EXISTS company_metadata_history_document_id_idx ON pdr_ai_v2_company_metadata_history(document_id)`);
await db.execute(sql`CREATE INDEX IF NOT EXISTS company_metadata_history_created_at_idx ON pdr_ai_v2_company_metadata_history(created_at)`);
await db.execute(sql`CREATE INDEX IF NOT EXISTS company_metadata_history_change_type_idx ON pdr_ai_v2_company_metadata_history(change_type)`);

console.log("✅ Tables created successfully!");
process.exit(0);
} catch (error) {
console.error("Error creating tables:", error);
process.exit(1);
}
}

createTables();
3 changes: 2 additions & 1 deletion scripts/ensure-pgvector.mjs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'dotenv/config';
import dotenv from "dotenv";
dotenv.config();
import postgres from "postgres";

const url = process.env.DATABASE_URL;
Expand Down
Loading
Loading