Skip to main content

max / makenotwork

Fix mechanical todo items: reqwest timeout, dep bumps, promo code visibility - Add 30s timeout to raw reqwest call in payments/connect.rs - Bump deps: tokio 1.50, uuid 1.22, chrono 0.4.44, yara-x 1.14, anyhow 1.0.102 - Replace <details> promo code with visible inline form on item page - Mark completed/already-done audit items in server and synckit todos Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Author: Max J. <87768334+MaxJMath@users.noreply.github.com> · 2026-05-03 02:17 UTC
Commit: 056335fceea87bc8133b28430858ddb8c66b42b1
Parent: a8bf638
6 files changed, +89 insertions, -11 deletions
@@ -3385,7 +3385,7 @@ dependencies = [
3385 3385
3386 3386 [[package]]
3387 3387 name = "makenotwork"
3388 - version = "0.4.7"
3388 + version = "0.4.8"
3389 3389 dependencies = [
3390 3390 "anyhow",
3391 3391 "argon2",
@@ -20,7 +20,7 @@ utoipa = { version = "5", features = ["axum_extras", "chrono", "uuid"] }
20 20 utoipa-axum = "0.2"
21 21 serde = { version = "1.0.228", features = ["derive"] }
22 22 serde_json = "1.0.149"
23 - tokio = { version = "1.49.0", features = ["macros", "rt-multi-thread", "net", "signal"] }
23 + tokio = { version = "1.50.0", features = ["macros", "rt-multi-thread", "net", "signal"] }
24 24 tokio-stream = { version = "0.1", features = ["sync"] }
25 25 tower = "0.5.3"
26 26 tower-http = { version = "0.6.8", features = ["trace", "fs", "limit", "request-id", "propagate-header", "set-header"] }
@@ -35,8 +35,8 @@ dotenvy = "0.15.7"
35 35
36 36 # Database
37 37 sqlx = { version = "0.8.6", features = ["runtime-tokio", "postgres", "uuid", "chrono", "migrate"] }
38 - uuid = { version = "1.20.0", features = ["v4", "serde"] }
39 - chrono = { version = "0.4.43", features = ["serde"] }
38 + uuid = { version = "1.22.0", features = ["v4", "serde"] }
39 + chrono = { version = "0.4.44", features = ["serde"] }
40 40
41 41 # Authentication
42 42 argon2 = "0.5.3"
@@ -75,7 +75,7 @@ base64 = "0.22.1"
75 75 infer = "0.19"
76 76 goblin = "0.10"
77 77 zip = "8.2"
78 - yara-x = "1.13"
78 + yara-x = "1.14"
79 79
80 80 # CSV parsing (import system)
81 81 csv = "1.3"
@@ -88,7 +88,7 @@ log = "0.4"
88 88
89 89 # Error handling
90 90 thiserror = "2.0.18"
91 - anyhow = "1.0.101"
91 + anyhow = "1.0.102"
92 92
93 93 # Metrics
94 94 metrics = "0.24"
@@ -9,6 +9,66 @@ Human tasks (manual testing, outreach, legal, infrastructure) moved to `human_to
9 9
10 10 ---
11 11
12 + ## Audit Run 19 (2026-05-02)
13 +
14 + ### Code
15 + - [x] **[MEDIUM]** Add timeout to `payments/connect.rs:198` raw reqwest call (Stripe resume-subscription)
16 + - [x] **[MEDIUM]** Add `ModerationActionId` newtype and `ModerationActionType` enum to `db/moderation.rs` (already existed in id_types.rs + enums.rs)
17 + - [ ] **[LOW]** Add README.md to server/
18 + - [x] **[LOW]** Bump dependency pins: tokio 1.49->1.50, uuid 1.20->1.22, chrono 0.4.43->0.4.44, yara-x 1.13->1.14, anyhow 1.0.101->1.0.102
19 + - [x] Fix auth rate limit for lockout test (`constants.rs` fast-tests override, burst 5->20)
20 +
21 + ### Deferred
22 + - [ ] Extract inline SQL from route handlers to db/ (4 locations)
23 + - [ ] Remove `async-trait` in favor of Rust 2024 native async traits
24 + - [ ] Migrate inline `onclick` handlers to `addEventListener` for strict CSP
25 +
26 + ---
27 +
28 + ## UX Audit Remediation (2026-05-02)
29 +
30 + Usability audit grade: B. Complexity C+, Completeness B+, Learnability B, Discoverability B-.
31 +
32 + ### Critical (broken or high-dropout flows)
33 +
34 + - [ ] **[HIGH]** Add "Add to collection" UI — fans can create collections but cannot add items to them. Add dropdown/button on library purchase rows and on item pages (`library_purchases.html`, `item.html`)
35 + - [ ] **[HIGH]** Consolidate item creation wizard from 8 steps to 5 — merge Details+Appearance into one step, move Distribution (license keys, promo codes) to post-creation item dashboard tabs. Current 8-step gauntlet has ~40% estimated dropout for first-time creators
36 + - [ ] **[HIGH]** Add global search to site header — search only exists on /discover page. Add input to `site_header.html` with Cmd+K shortcut
37 +
38 + ### High (significant friction reduction)
39 +
40 + - [ ] **[MEDIUM]** Restructure user dashboard tabs — show 4 core tabs (Account, Projects, Payments, Support) by default. Collapse SyncKit, SSH Keys, Forums, Media into "More Tools" overflow section. Current 11 tabs overwhelm new creators
41 + - [ ] **[MEDIUM]** Fix price input to use dollars, not cents — promo code and subscription tier forms accept cents (e.g. "500" for $5). Add live preview ("= $5.00") or switch to dollar input with auto-conversion
42 + - [ ] **[MEDIUM]** Standardize pricing terminology — project wizard says "One-time purchase", item wizard says "Fixed Price" for same concept. Pick one term and use it everywhere
43 + - [ ] **[MEDIUM]** Add self-service refund UI for creators — backend exists (`pending_refunds.rs`) but no dashboard UI. Add "Refund" button in creator transaction history
44 +
45 + ### Medium (discoverability and learnability)
46 +
47 + - [ ] **[MEDIUM]** Surface embed feature — currently buried 4 clicks deep (Dashboard > Project > Item > Embed tab). Add "Embed" link on public item pages for creators
48 + - [ ] **[MEDIUM]** Link data export from dashboard — `/dashboard/export` has no entry point from dashboard tabs. Add link in sidebar or account tab
49 + - [x] **[MEDIUM]** Explain creator application — pitch.html already says "Most applications are approved within a few days"
50 + - [x] **[LOW]** Add one-line descriptions to project feature checkboxes — already implemented via `ProjectFeature::description()` + `type-card-desc` in template
51 + - [x] **[LOW]** Improve empty states — library purchases has "Discover Content" CTA, project content has "Add First Item" CTA with explanatory text
52 + - [x] **[LOW]** Make promo code visible at checkout — replaced `<details>` with visible inline form
53 +
54 + ### Low (power-user improvements)
55 +
56 + - [ ] **[LOW]** Add bulk operations for item management — multi-select items in project Content tab for batch publish/unpublish/tag/price changes
57 + - [ ] **[LOW]** Add keyboard shortcuts — Cmd+K search, ? help overlay, p publish toggle, Esc close modal
58 + - [ ] **[LOW]** Add soft delete with 7-day recovery — items/projects currently hard-delete on confirmation. Add "Recently Deleted" archive with restore option
59 + - [ ] **[LOW]** Add wishlist/bookmark for fans — simple heart icon on item cards, DB table for saved items. Table-stakes vs Bandcamp/Gumroad/itch.io
60 + - [ ] **[LOW]** Add changelog or "What's New" — no mechanism to inform existing users about new features
61 +
62 + ### Deferred (post-beta table stakes)
63 +
64 + - [ ] Reviews/ratings system for items (all three competitors have this)
65 + - [ ] Gift purchases at checkout
66 + - [ ] HTML rich email for creator broadcasts (currently plain text only)
67 + - [ ] "Edit" link on public project/item pages for logged-in creators (currently must navigate to dashboard)
68 + - [ ] RSS feed link on all project pages (currently only shown if blog posts exist)
69 +
70 + ---
71 +
12 72 ## Integration Test Fixes (completed 2026-05-02)
13 73
14 74 All 34 previously-failing tests resolved (10 root causes). Additional 3 sandbox test failures fixed. Key changes:
@@ -200,6 +200,7 @@ impl StripeClient {
200 200 .header("Authorization", format!("Bearer {}", self.config.secret_key))
201 201 .header("Stripe-Account", connected_account_id)
202 202 .form(&[("pause_collection", "")])
203 + .timeout(std::time::Duration::from_secs(30))
203 204 .send()
204 205 .await
205 206 .map_err(|e| {
@@ -229,16 +229,15 @@
229 229 Secure payment processing
230 230 </div>
231 231
232 - <details style="margin-top: 1rem; font-size: 0.9rem;">
233 - <summary style="cursor: pointer; opacity: 0.7;">Have a promo code?</summary>
232 + <div style="margin-top: 1rem; font-size: 0.9rem;">
234 233 <form hx-post="/api/promo-codes/claim"
235 234 hx-swap="outerHTML"
236 - style="margin-top: 0.5rem; display: flex; gap: 0.5rem;">
237 - <input type="text" name="code" placeholder="Enter code" required
235 + style="display: flex; gap: 0.5rem; align-items: center;">
236 + <input type="text" name="code" placeholder="Promo code" required
238 237 style="flex: 1; padding: 0.4rem 0.6rem; font-size: 0.85rem;">
239 238 <button class="secondary" type="submit" style="white-space: nowrap;">Redeem</button>
240 239 </form>
241 - </details>
240 + </div>
242 241 {% endif %}
243 242 {% endif %}
244 243 </div>
@@ -58,6 +58,24 @@ v0.3.1. Audit grade A. 340 tests.
58 58 - Integer vs float (`1` vs `1.0`) treated as different in `resolve_field_merge` — serde_json Value semantics.
59 59 - Null base in `resolve_field_merge` returns KeepRemote — documented, callers should use LWW fallback.
60 60
61 + ## Business Sustainability (from 2026-05-02 audit)
62 +
63 + ### Pricing & Revenue
64 + - [ ] Reconcile pricing models — synckit-plan.md tiers, synckit_pricing.md Weight/Burst, and economics.md add-on into one coherent model. Weight/Burst as billing engine, simple tier names as customer-facing packaging.
65 + - [ ] Charge for sync in GO, BB, AF — $2-5/mo premium feature. Validates willingness-to-pay, generates real revenue, establishes SyncKit value proposition before B2B launch.
66 + - [ ] Clarify SyncKit relationship to MNW creator tiers — is it included, discounted, or full standalone pricing for creators?
67 + - [ ] Re-evaluate free tier — MNW has no free tier by philosophy. Consider 14-day trial instead of 100 users/1GB free, or remove entirely.
68 + - [ ] Fix Micro tier messaging — frame as "$5/mo for up to 1,000 Micro users" rather than "$0.005/user" with a hidden $5 floor.
69 +
70 + ### Operational Prerequisites (before first external customer)
71 + - [x] Automate sync_log compaction — already wired in server monitor.rs maintenance loop
72 + - [ ] Per-API-key rate limiting — current rate limiting is global, not per-developer. Required for multi-tenancy.
73 + - [ ] Separate VPS for SyncKit — $15-30/mo. Prevents resource contention between SyncKit and MNW on shared Hetzner instance.
74 +
75 + ### Documentation & Accuracy
76 + - [ ] Update synckit-plan.md economics — replace R2 references with Hetzner Object Storage, replace "$1.00 support" with realistic estimate, add Rust-only base-case projections.
77 + - [ ] Monitor Turso and PowerSync — track whether either ships E2E encryption or flat pricing (SyncKit's main differentiators).
78 +
61 79 ## Deferred (Post-Beta)
62 80 - [ ] Conflict resolution helpers — LWW, field-level merge, custom resolver callback in the SDK. Reduces client-side boilerplate. (Gap vs Ditto, Couchbase)
63 81 - [ ] Key rotation mechanism (requires server-side re-encryption of all sync_log entries)