A mobile-first web app that lets you photograph second-hand products, generate complete WooCommerce listings with Claude AI, and publish them in seconds β without touching the slow WordPress admin.
Running on Android Chrome. The app lives entirely inside the browser β no native install required.
π± Camera / gallery
β
βΌ
Sharp β detect orientation
Portrait β 9:16 β 720Γ1280
Landscape β 16:9 β 1280Γ720 (smart attention crop, WebP q80)
Square β 1:1 β 1080Γ1080
β
βΌ
WP REST API βββββββββββββββββββΊ WordPress Media Library
/wp-json/wp/v2/media (real attachment ID returned)
β
βΌ
Claude claude-sonnet-4-6 βββββββΊ Full product listing
researches specs + user notes title / descriptions / SKU / tags / price
+ analyses uploaded photos
β
βΌ
User reviews & edits
β
βΌ
WC REST API ββββββββββββββββββββΊ WooCommerce product (live instantly)
/wp-json/wc/v3/products handles all DB writes + cache + hooks
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β SecondSell App (Railway) β
β β
β POST /api/auth/login β cookie-based session auth β
β POST /api/upload β Sharp + WP REST API β
β POST /api/ai/describe β Claude claude-sonnet-4-6 β
β GET /api/products/categories β WC REST API β
β POST /api/products β WC REST API β
β GET /api/health β WP/WC reachability check β
β β
β public/ (vanilla JS, mobile-first, no bundler) β
ββββββββββββ¬βββββββββββββββββββββββββββββββββββββββββββββββ
β WP/WC REST API
βΌ
WordPress + WooCommerce
(images + products)
| Requirement | Notes |
|---|---|
| WordPress 5.6+ | Application Passwords feature |
| WooCommerce 3.7+ | wp_wc_product_meta_lookup table |
| HTTPS on WordPress | Required for Application Passwords |
| Anthropic API key | console.anthropic.com |
git clone <repo> && cd secondsell
npm install- WP Admin β Users β Edit your profile
- Scroll to Application Passwords
- Name:
SecondSellβ Add New Application Password - Copy the generated password β it's shown once
- WP Admin β WooCommerce β Settings β Advanced β REST API
- Add key β Description:
SecondSell, User: admin, Permissions: Read/Write - Copy the Consumer Key and Consumer Secret
cp .env.example .envWP_URL=https://your-wordpress-site.com
WP_USER=your-wp-username
WP_APP_PASSWORD="xxxx xxxx xxxx xxxx xxxx xxxx"
WC_CONSUMER_KEY=ck_...
WC_CONSUMER_SECRET=cs_...
BASIC_AUTH_USER=admin
BASIC_AUTH_PASS="your-app-password"
ANTHROPIC_API_KEY=sk-ant-...Note: If your password contains
#,!, or other shell-special characters, wrap it in double quotes in.env.
npm run dev
# β http://localhost:3000For camera access on iOS/Android, use HTTPS (e.g. ngrok) β browsers require HTTPS for getUserMedia.
- Push to GitHub
- Railway β New Project β Deploy from GitHub repo
- Set all env vars in Railway β Service β Variables
No Railway Volume needed β images live in WordPress's own media library.
/
βββ images/ β screenshots and documentation assets (committed to git)
βββ public/ β frontend (vanilla JS, mobile-first, no bundler)
β βββ index.html
β βββ login.html
β βββ css/style.css
β βββ js/app.js
βββ routes/ β Express route handlers
β βββ upload.js β Sharp pipeline + optional background removal
β βββ ai.js β Claude claude-sonnet-4-6
β βββ products.js β WooCommerce product/category API
β βββ auth.js β Login / logout
β βββ health.js β WP/WC reachability check
βββ middleware/auth.js β HMAC-SHA256 cookie session guard
βββ utils/wcApi.js β WP + WC REST API client
βββ server.js β Express app entry point
βββ .env.example β environment variable template
| Input orientation | Detected by | Cropped to | Output |
|---|---|---|---|
| Portrait (tall) | ratio < 0.80 | 9:16 | 720 Γ 1280 WebP |
| Landscape (wide) | ratio > 1.25 | 16:9 | 1280 Γ 720 WebP |
| Square / near-sq | 0.80 β 1.25 | 1:1 | 1080 Γ 1080 WebP |
- Crop strategy:
sharp.strategy.attentionβ analyses saliency and entropy to keep the focal point centred. - Never upscaled: small images stay small.
- EXIF rotation applied before any resize.
- WebP quality 80 β typically 40β120 KB per image.
{ "username": "admin", "password": "secret" }Sets ss_session cookie on success.
Returns live WooCommerce categories:
{ "success": true, "categories": [{ "id": 15, "name": "Electronics", "count": 8 }] }Optimise + upload images to WordPress media library.
Request: multipart/form-data, field images, up to 10 files.
Response:
{
"images": [
{
"id": 247,
"url": "https://site.com/wp-content/uploads/2026/03/uuid.webp",
"width": 720,
"height": 1280,
"orientation": "portrait",
"aspect": "9:16",
"sizeKb": 68
}
]
}Generate a product listing with Claude. Passes uploaded image URLs as vision content.
Request:
{
"productName": "Sony WH-1000XM4",
"condition": "good",
"userContext": "Includes case and USB-C cable",
"imageUrls": ["https://..."]
}condition: new | like_new | good | fair | poor
Create a WooCommerce product via REST API.
Request:
{
"title": "Sony WH-1000XM4 Wireless Headphones",
"shortDescription": "Industry-leading ANC, 30h battery.",
"fullDescription": "<h3>Overview</h3><p>β¦</p>",
"price": "185.00",
"sku": "SH-SONY-WH1000XM4-001",
"quantity": 1,
"categoryId": 15,
"images": [{ "id": 247, "url": "https://β¦" }],
"tags": ["sony", "headphones"]
}{
"status": "ok",
"wpUrl": "https://site.com",
"wpApi": "reachable",
"wcApi": "configured",
"claude": "configured"
}| Symptom | Cause | Fix |
|---|---|---|
| Login fails | # in password not quoted |
Wrap BASIC_AUTH_PASS in double quotes in .env |
| Upload 401 | Wrong WP_USER / WP_APP_PASSWORD |
Regenerate WordPress Application Password |
| Upload 403 | REST API blocked by security plugin | Wordfence β allow REST API; re-save Permalinks |
| Product 401 | Wrong consumer key/secret | Regenerate WC API key with Read/Write |
| Product 403 | Key is Read-only | Edit key β set Permissions to Read/Write |
| AI fails | Wrong/truncated API key | Copy full key from console.anthropic.com |
| Wrong crop | EXIF not applied | Sharp .rotate() is called first β should be handled |
βββ server.js
βββ middleware/auth.js HMAC-SHA256 cookie session
βββ routes/
β βββ auth.js Login / logout
β βββ upload.js Sharp optimise β WP media
β βββ ai.js Claude description + vision
β βββ products.js WC categories + product creation
β βββ health.js System status
βββ utils/
β βββ wcApi.js WP + WC REST API client
βββ public/
β βββ index.html 4-step mobile UI
β βββ login.html Login page
β βββ css/style.css Mobile-first glassmorphism styles
β βββ js/app.js Vanilla JS
βββ specs/ Feature specifications
βββ CLAUDE.md AI coding guide
βββ CONSTITUTION.md Project rules
βββ .env.example
- All credentials in environment variables β never in source code
- Cookie session uses HMAC-SHA256 β no plaintext tokens
- WP Application Password is scoped and revocable
- WC API key is scoped to Read/Write products only
- Multer enforces
image/*type and 30 MB size limit - Sharp processes all uploads in memory β raw bytes never written to disk
- API responses never include stack traces
Eduardo Arana & Soda [bot]
MIT
