Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
b6617f1
Merchant Moltbook: full commerce platform refactor
SaiPaladugu Feb 11, 2026
9a49045
Add Railway deployment + Docker configs
SaiPaladugu Feb 11, 2026
7b75151
Fix commerce loop: lifecycle prompts + agent context + multi-listing
SaiPaladugu Feb 11, 2026
8ca8239
Fix SSL for Cloud SQL proxy: disable SSL when sslmode=disable in DATA…
SaiPaladugu Feb 11, 2026
130883f
Fix image storage, backups, and monitoring
SaiPaladugu Feb 11, 2026
9d0c7b6
Rebalance agent action diversity for realistic marketplace
SaiPaladugu Feb 11, 2026
90d74b7
Add supply-side check: force product creation and price updates
SaiPaladugu Feb 11, 2026
2b9e8d1
Serve images via GCS signed URLs to bypass IAP
SaiPaladugu Feb 11, 2026
23f208b
Fix signed URL crash: add try-catch fallback and grant signBlob permi…
SaiPaladugu Feb 12, 2026
1d11268
Extend signed URL lifetime to 7 days
SaiPaladugu Feb 12, 2026
e1b8020
Add GCP E2E validation suite (74 tests, all passing)
SaiPaladugu Feb 12, 2026
d66a0fb
Add rate limiter pause before negative test phase
SaiPaladugu Feb 12, 2026
ec874f1
Add OPTIONS method and credentials to CORS config
SaiPaladugu Feb 12, 2026
e4cc09e
Bundle Next.js frontend into Express — single domain, no CORS/IAP issues
SaiPaladugu Feb 12, 2026
160605e
Add .gcloudignore to include frontend/ in Cloud Build context
SaiPaladugu Feb 12, 2026
78dc8c7
Fix frontend proxy: readiness check, error handling, 1Gi memory
SaiPaladugu Feb 12, 2026
0e9478d
Fix .gcloudignore: use /node_modules/ to only exclude root, include f…
SaiPaladugu Feb 12, 2026
ded4778
Disable Helmet CSP for Next.js inline scripts + patch client URLs to …
SaiPaladugu Feb 12, 2026
11db932
Add /api/check-image stub for frontend image validation
SaiPaladugu Feb 12, 2026
0e02966
Add /_next/image redirect to original GCS URL (skip optimization)
SaiPaladugu Feb 12, 2026
e100cac
Add deploy-frontend.sh script for one-command frontend deploys
SaiPaladugu Feb 12, 2026
237e6a8
Add stats page API, listing offers endpoint, and duplicate prevention
Feb 12, 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
890 changes: 890 additions & 0 deletions .cursor/plans/merchant_moltbook_refactor_4fe8076f.plan.md

Large diffs are not rendered by default.

19 changes: 19 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Root node_modules only (installed by npm ci in Dockerfile)
node_modules

# But include frontend/node_modules (part of Next.js standalone build)
!frontend/node_modules

.env
.env.local
.env.*.local
.local
uploads
.git
.cursor
docs
*.md
sai.zip
frontend/Dockerfile
frontend/cloudbuild.yaml
frontend/.dockerignore
27 changes: 27 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,30 @@ BASE_URL=http://localhost:3000
# Twitter/X OAuth (for verification)
TWITTER_CLIENT_ID=
TWITTER_CLIENT_SECRET=

# Image Generation (single key or comma-separated pool for rate limit rotation)
IMAGE_PROVIDER=openai
IMAGE_API_KEY=
# IMAGE_API_KEYS=key1,key2,key3
IMAGE_MODEL=dall-e-3
IMAGE_SIZE=1024x1024
IMAGE_OUTPUT_DIR=./uploads
IMAGE_BASE_URL=https://proxy.shopify.ai/v1

# LLM Text Inference (single key or comma-separated pool for rate limit rotation)
LLM_PROVIDER=openai
LLM_API_KEY=
# LLM_API_KEYS=key1,key2,key3
LLM_MODEL=gpt-4o
LLM_BASE_URL=https://proxy.shopify.ai/v1
TICK_MS=5000
RUN_SEED=42

# Operator Control
OPERATOR_KEY=change-this-in-production

# Anti-trivial Gating
MIN_QUESTION_LEN=20
MIN_OFFER_PRICE_CENTS=1
MIN_OFFER_MESSAGE_LEN=10
MIN_LOOKING_FOR_CONSTRAINTS=2
16 changes: 16 additions & 0 deletions .gcloudignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Root node_modules only (rebuilt by npm ci in Dockerfile)
# IMPORTANT: Do NOT use bare "node_modules" — it excludes frontend/node_modules too
/node_modules/

.env
.env.local
.env.*.local
.local/
uploads/
.git/
.cursor/
docs/
sai.zip
frontend/Dockerfile
frontend/cloudbuild.yaml
frontend/.dockerignore
79 changes: 79 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
name: E2E Tests

on:
push:
branches: [main]
pull_request:
branches: [main]

jobs:
test:
runs-on: ubuntu-latest

services:
postgres:
image: postgres:16-alpine
env:
POSTGRES_USER: moltbook
POSTGRES_PASSWORD: moltbook
POSTGRES_DB: moltbook
ports:
- 5432:5432
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5

env:
DATABASE_URL: postgresql://moltbook:moltbook@localhost:5432/moltbook
NODE_ENV: development
PORT: 3000
OPERATOR_KEY: ci-operator-key
BASE_URL: http://localhost:3000
JWT_SECRET: ci-jwt-secret

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'

- name: Install dependencies
run: npm ci

- name: Apply base schema
run: |
PGPASSWORD=moltbook psql -h localhost -U moltbook -d moltbook -f scripts/schema.sql

- name: Run migrations
run: npm run db:migrate

- name: Start API server
run: |
npm start &
echo "Waiting for API to be ready..."
for i in $(seq 1 15); do
if curl -s http://localhost:3000/api/v1/health | grep -q '"success":true'; then
echo "API is ready!"
break
fi
echo " attempt $i..."
sleep 2
done

- name: Seed demo data
run: node scripts/seed.js

- name: Run smoke test
run: node scripts/smoke-test.js

- name: Run full E2E test suite
run: node scripts/full-test.js

- name: Run concurrency tests
run: node scripts/concurrency-test.js
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,7 @@ dist/
build/
coverage/
*.tgz
uploads/
.local/
frontend/
sai.zip
23 changes: 23 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
FROM node:20-alpine

WORKDIR /app

# Copy backend package files and install deps
COPY package.json package-lock.json ./
RUN npm ci --production

# Copy backend source
COPY src/ src/
COPY scripts/ scripts/

# Copy frontend standalone build (includes its own node_modules)
COPY frontend/ frontend/

# Create uploads directory
RUN mkdir -p uploads

# Expose port
EXPOSE 3000

# Default command: apply schema + migrations + start API + frontend
CMD ["node", "scripts/start-production.js"]
13 changes: 13 additions & 0 deletions Dockerfile.worker
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
FROM node:20-alpine

WORKDIR /app

COPY package.json package-lock.json ./
RUN npm ci --production

COPY . .

RUN mkdir -p uploads

# Run the worker process (not the API server)
CMD ["node", "scripts/run-worker.js"]
41 changes: 41 additions & 0 deletions build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#!/bin/bash
# Build script for moltbook-api
# Creates a production-ready Docker image

set -e

# Configuration
IMAGE_NAME="${IMAGE_NAME:-moltbook-api}"
IMAGE_TAG="${IMAGE_TAG:-latest}"
REGISTRY="${REGISTRY:-}"

echo "Building moltbook-api..."
echo "========================"
echo "Image: ${IMAGE_NAME}:${IMAGE_TAG}"
echo ""

# Build the Docker image
docker build -t "${IMAGE_NAME}:${IMAGE_TAG}" .

# Also build the worker image
echo ""
echo "Building worker image..."
docker build -f Dockerfile.worker -t "${IMAGE_NAME}-worker:${IMAGE_TAG}" .

echo ""
echo "Build complete!"
echo ""
echo "Images created:"
echo " - ${IMAGE_NAME}:${IMAGE_TAG} (API server)"
echo " - ${IMAGE_NAME}-worker:${IMAGE_TAG} (Agent runtime worker)"
echo ""
echo "To run locally:"
echo " docker run -p 3000:3000 --env-file .env ${IMAGE_NAME}:${IMAGE_TAG}"
echo ""
echo "To push to registry:"
if [ -n "$REGISTRY" ]; then
echo " docker tag ${IMAGE_NAME}:${IMAGE_TAG} ${REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG}"
echo " docker push ${REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG}"
else
echo " Set REGISTRY env var and re-run, or manually tag and push"
fi
Loading