From 4852e657a877386d525a706a3a665041d5d43aaf Mon Sep 17 00:00:00 2001 From: Ben Bracamonte Date: Mon, 29 Jun 2026 22:24:44 -0500 Subject: [PATCH] =?UTF-8?q?docs:=20make=20repo=20public-ready=20=E2=80=94?= =?UTF-8?q?=20add=20MIT=20LICENSE,=20fix=20README=20drift,=20archive=20pla?= =?UTF-8?q?nning=20docs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add MIT LICENSE - README: correct image-gen defaults (gpt-image-2), copy model (Opus 4.8), remove deleted HUMAN_REVIEW_ENABLED flag, document dashboard package and needs_review approval flow, mark Railway/cron as planned-not-deployed, fix table count, add License section - Move internal AUDIT_*/PLAN_*/BUGFIX/BACKLOG/AGENT_OVERVIEW docs to docs/internal/ Co-Authored-By: Claude Opus 4.8 (1M context) --- LICENSE | 21 +++++++++++ README.md | 37 +++++++++++++------ .../internal/AGENT_OVERVIEW.html | 0 AUDIT_4.md => docs/internal/AUDIT_4.md | 0 AUDIT_5.md => docs/internal/AUDIT_5.md | 0 .../internal/AUDIT_CAPABILITIES.md | 0 BACKLOG.md => docs/internal/BACKLOG.md | 0 .../internal/BUGFIX_PLAN.md | 0 .../internal/PLAN_MOCKUP_RENDERER.md | 0 .../internal/PLAN_SCOUT_VISION.md | 0 .../internal/PLAN_birefnet_bg_removal.md | 0 .../PLAN_dashboard_history_and_active_edit.md | 0 .../PLAN_listing_add_catalog_colors.md | 0 .../internal/PLAN_listing_etsy_mock_mode.md | 0 .../internal/PLAN_listing_image_management.md | 0 .../internal/PLAN_multi_product_types.md | 0 .../PLAN_shirt_color_size_variants.md | 0 17 files changed, 46 insertions(+), 12 deletions(-) create mode 100644 LICENSE rename AGENT_OVERVIEW.html => docs/internal/AGENT_OVERVIEW.html (100%) rename AUDIT_4.md => docs/internal/AUDIT_4.md (100%) rename AUDIT_5.md => docs/internal/AUDIT_5.md (100%) rename AUDIT_CAPABILITIES.md => docs/internal/AUDIT_CAPABILITIES.md (100%) rename BACKLOG.md => docs/internal/BACKLOG.md (100%) rename BUGFIX_PLAN.md => docs/internal/BUGFIX_PLAN.md (100%) rename PLAN_MOCKUP_RENDERER.md => docs/internal/PLAN_MOCKUP_RENDERER.md (100%) rename PLAN_SCOUT_VISION.md => docs/internal/PLAN_SCOUT_VISION.md (100%) rename PLAN_birefnet_bg_removal.md => docs/internal/PLAN_birefnet_bg_removal.md (100%) rename PLAN_dashboard_history_and_active_edit.md => docs/internal/PLAN_dashboard_history_and_active_edit.md (100%) rename PLAN_listing_add_catalog_colors.md => docs/internal/PLAN_listing_add_catalog_colors.md (100%) rename PLAN_listing_etsy_mock_mode.md => docs/internal/PLAN_listing_etsy_mock_mode.md (100%) rename PLAN_listing_image_management.md => docs/internal/PLAN_listing_image_management.md (100%) rename PLAN_multi_product_types.md => docs/internal/PLAN_multi_product_types.md (100%) rename PLAN_shirt_color_size_variants.md => docs/internal/PLAN_shirt_color_size_variants.md (100%) diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..a3727fc --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 Ben Bracamonte + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index 2bfc184..1ada16a 100644 --- a/README.md +++ b/README.md @@ -15,9 +15,9 @@ Etsy trends → Scout → Design → Listing → (Etsy ↔ Printify fulfillment) **Scout** runs nightly. It scans Etsy for trending niches, calls Claude to extract structured trend briefs (keywords, price targets, color palette), and writes them to `trend_briefs`. Exact-match and semantic dedup via Claude prevent near-duplicate briefs from flooding the pipeline. -**Design** polls every 15 minutes. It picks up pending briefs, calls Claude to craft a FLUX-safe image prompt, generates a 300dpi print-ready PNG via fal.ai (FLUX Pro 1.1), and uploads the result to Supabase Storage. Identical prompts are detected by SHA-256 hash and reuse the prior image rather than paying for a duplicate fal.ai call. +**Design** polls every 15 minutes. It picks up approved briefs, calls Claude to craft an image prompt (or uses the operator-authored `image_description` verbatim when present), generates a 300dpi print-ready PNG via fal.ai, and uploads the result to Supabase Storage. The image backend is selected per-brief: `fal_gpt_image_2` (OpenAI gpt-image-2, the default), `fal_flux_pro` (FLUX Pro 1.1), or `fal_nano_banana_2` (Gemini-3). Identical prompts are detected by SHA-256 hash and reuse the prior image rather than paying for a duplicate fal.ai call. -**Listing** polls every 15 minutes. It creates a hidden Printify product to generate mockup images, writes SEO-optimized listing copy via Claude, then publishes to Etsy (draft → images → activate). If `HUMAN_REVIEW_ENABLED=true`, listings pause at `needs_review` for manual approval before going live. +**Listing** polls every 15 minutes. It creates a hidden Printify product to generate mockup images, writes SEO-optimized listing copy via Claude, then pauses every listing at `needs_review`. There is no auto-publish path: an operator approves the listing in the dashboard, which flips it to `pending_publish`, and the next Listing run drives the Etsy publish (draft → inventory → images → activate). The full Etsy seller-policy compliance gate runs twice — once before copy generation and again at publish time. **Ledger** polls Etsy receipts every 30 minutes for paid orders. Each receipt is logged once (idempotent via a unique constraint on `etsy_order_id`) with sale price in buyer currency, USD-normalized total, computed Etsy fees, looked-up print cost, derived margin, and buyer country. A low-margin Slack warning fires per-order; a separate daily cron emits a revenue/margin digest via Slack and email. @@ -29,11 +29,13 @@ Etsy trends → Scout → Design → Listing → (Etsy ↔ Printify fulfillment) |---|---| | Scout + Design | Python 3.12, httpx, pydantic, structlog | | Listing + Ledger | TypeScript / Node.js 20, Zod, Bottleneck | -| AI reasoning | Claude Sonnet 4 (`claude-sonnet-4-20250514`) | -| Image generation | fal.ai — FLUX Pro 1.1 | +| Dashboard | Next.js (TypeScript), Supabase Realtime | +| Scout/Design reasoning | Claude Sonnet 4 (`claude-sonnet-4-20250514`) | +| Listing copy | Latest flagship Claude — currently Opus 4.8 (`claude-opus-4-8`) | +| Image generation | fal.ai — gpt-image-2 (default), FLUX Pro 1.1, or Gemini-3 (per-brief) | | Database + Storage | Supabase (Postgres) | | Print fulfillment | Etsy's native Printify integration (out of band) | -| Hosting + cron | Railway | +| Hosting + cron | Railway (planned — not deployed; agents currently run manually) | | Alerts | Slack incoming webhooks + Resend email | --- @@ -48,10 +50,12 @@ presswork/ │ ├── scout/ # Agent 1 (Python) — Etsy trend scraper │ ├── design/ # Agent 2 (Python) — fal.ai image generation │ ├── listing/ # Agent 3 (TypeScript) — Etsy listing publisher -│ └── ledger/ # Agent 4 (TypeScript) — receipt polling + economics digest +│ ├── ledger/ # Agent 4 (TypeScript) — receipt polling + economics digest +│ └── dashboard/ # Next.js control plane — review gates, manual triggers ├── infra/ -│ ├── railway.toml +│ ├── railway.toml # planned service definitions (cron schedules commented out) │ └── supabase/migrations/ +├── docs/ # printify integration notes + docs/internal/ planning archive ├── tests/e2e/ # Full-pipeline smoke test └── .github/workflows/ # CI — lint, typecheck, unit tests ``` @@ -102,7 +106,8 @@ See `.env.example` for the full list. Key ones: | `PRINTIFY_API_TOKEN` / `PRINTIFY_SHOP_ID` | Printify credentials | | `SUPABASE_URL` / `SUPABASE_SERVICE_ROLE_KEY` | Supabase project | | `SLACK_WEBHOOK_URL` | Incoming webhook for error alerts (optional) | -| `HUMAN_REVIEW_ENABLED` | `true` to pause listings before publishing (default) | +| `ETSY_MOCK_MODE` | `true` runs the full publish flow against canned Etsy fixtures (no Etsy creds needed) | +| `DASHBOARD_ALLOWED_EMAILS` | Comma-separated owner allowlist for dashboard sign-in | --- @@ -162,7 +167,7 @@ Integration tests and the E2E smoke test are not run in CI — they require a li ## Database schema -Five tables — agents communicate exclusively through Supabase, never by calling each other directly. +Four core tables — agents communicate exclusively through Supabase, never by calling each other directly. | Table | Written by | Read by | |---|---|---| @@ -177,9 +182,11 @@ Status columns enforce strict one-way transitions (`pending → processing → d ## Deployment -Each agent runs as a separate Railway service. Railway auto-deploys from `main` on push. Configure environment variables in the Railway dashboard — never commit secrets. +> **Status: manual only.** Nothing in this system runs on a schedule today. No cron is deployed and no agent fires on its own — every agent is a one-shot, drain-and-exit process invoked by the operator (see "Running agents manually" above). The table below is the *planned* Railway topology for if/when unattended automation is deliberately turned on; the schedules in `infra/railway.toml` are commented out. -| Service | Type | Schedule | +The intended layout is one Railway service per agent, auto-deploying from `main` on push, with environment variables configured in the Railway dashboard — never committed. + +| Service | Type | Schedule (planned) | |---|---|---| | `scout` | Cron | Nightly at 2am | | `design` | Cron | Every 15 min | @@ -187,7 +194,7 @@ Each agent runs as a separate Railway service. Railway auto-deploys from `main` | `ledger-cron-receipts` | Cron | Every 30 min | | `ledger-cron-daily-digest` | Cron | Daily at 13:00 UTC | -> **Note:** Etsy API access requires a separate storefront application. The pipeline runs fully against mocks until live credentials are available. Flip `HUMAN_REVIEW_ENABLED=false` only after manually verifying a listing end-to-end in a sandbox shop. +> **Note:** Etsy API access requires a separate storefront application. The pipeline runs fully against mocks (`ETSY_MOCK_MODE=true`) until live credentials are available. Every agent's output stays human-gated regardless of deployment — listings always pause at `needs_review` until an operator approves them in the dashboard. --- @@ -201,3 +208,9 @@ Etsy fees (at $24.99): ~$2.12 Net margin at $24.99: ~$9.87 (39%) Pricing floor: $21.25 (2.5× print cost) ``` + +--- + +## License + +[MIT](./LICENSE) © Ben Bracamonte diff --git a/AGENT_OVERVIEW.html b/docs/internal/AGENT_OVERVIEW.html similarity index 100% rename from AGENT_OVERVIEW.html rename to docs/internal/AGENT_OVERVIEW.html diff --git a/AUDIT_4.md b/docs/internal/AUDIT_4.md similarity index 100% rename from AUDIT_4.md rename to docs/internal/AUDIT_4.md diff --git a/AUDIT_5.md b/docs/internal/AUDIT_5.md similarity index 100% rename from AUDIT_5.md rename to docs/internal/AUDIT_5.md diff --git a/AUDIT_CAPABILITIES.md b/docs/internal/AUDIT_CAPABILITIES.md similarity index 100% rename from AUDIT_CAPABILITIES.md rename to docs/internal/AUDIT_CAPABILITIES.md diff --git a/BACKLOG.md b/docs/internal/BACKLOG.md similarity index 100% rename from BACKLOG.md rename to docs/internal/BACKLOG.md diff --git a/BUGFIX_PLAN.md b/docs/internal/BUGFIX_PLAN.md similarity index 100% rename from BUGFIX_PLAN.md rename to docs/internal/BUGFIX_PLAN.md diff --git a/PLAN_MOCKUP_RENDERER.md b/docs/internal/PLAN_MOCKUP_RENDERER.md similarity index 100% rename from PLAN_MOCKUP_RENDERER.md rename to docs/internal/PLAN_MOCKUP_RENDERER.md diff --git a/PLAN_SCOUT_VISION.md b/docs/internal/PLAN_SCOUT_VISION.md similarity index 100% rename from PLAN_SCOUT_VISION.md rename to docs/internal/PLAN_SCOUT_VISION.md diff --git a/PLAN_birefnet_bg_removal.md b/docs/internal/PLAN_birefnet_bg_removal.md similarity index 100% rename from PLAN_birefnet_bg_removal.md rename to docs/internal/PLAN_birefnet_bg_removal.md diff --git a/PLAN_dashboard_history_and_active_edit.md b/docs/internal/PLAN_dashboard_history_and_active_edit.md similarity index 100% rename from PLAN_dashboard_history_and_active_edit.md rename to docs/internal/PLAN_dashboard_history_and_active_edit.md diff --git a/PLAN_listing_add_catalog_colors.md b/docs/internal/PLAN_listing_add_catalog_colors.md similarity index 100% rename from PLAN_listing_add_catalog_colors.md rename to docs/internal/PLAN_listing_add_catalog_colors.md diff --git a/PLAN_listing_etsy_mock_mode.md b/docs/internal/PLAN_listing_etsy_mock_mode.md similarity index 100% rename from PLAN_listing_etsy_mock_mode.md rename to docs/internal/PLAN_listing_etsy_mock_mode.md diff --git a/PLAN_listing_image_management.md b/docs/internal/PLAN_listing_image_management.md similarity index 100% rename from PLAN_listing_image_management.md rename to docs/internal/PLAN_listing_image_management.md diff --git a/PLAN_multi_product_types.md b/docs/internal/PLAN_multi_product_types.md similarity index 100% rename from PLAN_multi_product_types.md rename to docs/internal/PLAN_multi_product_types.md diff --git a/PLAN_shirt_color_size_variants.md b/docs/internal/PLAN_shirt_color_size_variants.md similarity index 100% rename from PLAN_shirt_color_size_variants.md rename to docs/internal/PLAN_shirt_color_size_variants.md