max / makenotwork
99 files changed,
+3512 insertions,
-785 deletions
| @@ -6,7 +6,7 @@ Binding commitments from Makenot.work to every creator on the platform. These ar | |||
| 6 | 6 | ||
| 7 | 7 | ## Revenue | |
| 8 | 8 | ||
| 9 | - | **Guarantee:** 100% of fan payments reach the creator, minus only the payment processor's fee (currently Stripe, ~3%). | |
| 9 | + | **Guarantee:** 0% platform fee on fan payments. The only deduction is the payment processor's fee (currently Stripe, ~3%). | |
| 10 | 10 | ||
| 11 | 11 | - No platform percentage cut, ever. | |
| 12 | 12 | - No transaction fees, payout fees, or skimming. |
| @@ -10,7 +10,7 @@ Flat fee. All your revenue passes through to you. | |||
| 10 | 10 | 2. **Upload content** — audio, text, or digital files | |
| 11 | 11 | 3. **Organize** using hierarchical tags and projects | |
| 12 | 12 | 4. **Set pricing** — free, pay-what-you-want, fixed price, or subscription | |
| 13 | - | 5. **Get paid** — 100% of fan payments go to you | |
| 13 | + | 5. **Get paid** — 0% platform fee, only Stripe processing | |
| 14 | 14 | ||
| 15 | 15 | ## For Fans | |
| 16 | 16 | ||
| @@ -40,7 +40,7 @@ We never touch creator revenue. Payments go directly to creator-controlled Strip | |||
| 40 | 40 | ||
| 41 | 41 | ## The Model | |
| 42 | 42 | ||
| 43 | - | You pay a monthly subscription based on content type ($10-40). Your fan revenue is yours — 100% minus payment processing (~3% from Stripe). | |
| 43 | + | You pay a monthly subscription based on content type ($10-40). We take 0% of your fan revenue — the only deduction is payment processing (~3% from Stripe). | |
| 44 | 44 | ||
| 45 | 45 | We're funded by subscriptions, not by your success. No ads, no percentage cuts, no hidden fees. | |
| 46 | 46 | ||
| @@ -92,7 +92,7 @@ Video and streaming cost more than audio. Audio costs more than text. The prices | |||
| 92 | 92 | - Project organization (`/p/projectname`) | |
| 93 | 93 | - Permanent content links (`/i/UUID`) | |
| 94 | 94 | - Complete data export (projects, items, blog posts, transactions) | |
| 95 | - | - Direct fan payments (you keep 100%) | |
| 95 | + | - Direct fan payments (0% platform fee) | |
| 96 | 96 | - Contact sharing with fans (opt-in at purchase) | |
| 97 | 97 | - RSS feed generation (project + blog feeds) | |
| 98 | 98 | - License keys, discount codes, download codes |
| @@ -52,7 +52,7 @@ Everything listed here is live and working. | |||
| 52 | 52 | ||
| 53 | 53 | ### Payments & Stripe | |
| 54 | 54 | ||
| 55 | - | - **100% revenue passthrough**: Payments go directly to creator-controlled Stripe accounts | |
| 55 | + | - **0% platform fee**: Payments go directly to creator-controlled Stripe accounts | |
| 56 | 56 | - **Stripe Connect onboarding**: Guided setup, connected account status tracking | |
| 57 | 57 | - **Webhook processing**: Checkout completion, refunds, subscription lifecycle (active, past due, canceled), renewal billing | |
| 58 | 58 | - **Atomic checkout**: Row-level locking prevents double-purchases and race conditions | |
| @@ -72,6 +72,7 @@ Everything listed here is live and working. | |||
| 72 | 72 | ||
| 73 | 73 | - **Source-available codebase**: PolyForm Noncommercial 1.0.0 | |
| 74 | 74 | - **Creator waitlist**: Invite-only launch with lottery waves and hand-picked approvals | |
| 75 | + | - **Admin CLI** (`mnw-admin`): Command-line tool for waitlist management, creator approval, spam flagging, wave execution, and stats -- connects directly to the database, no web UI needed | |
| 75 | 76 | - **Documentation**: Server-rendered from markdown, auto-linked cross-references | |
| 76 | 77 | - **Health monitoring**: Real uptime tracking, database status, service connectivity checks | |
| 77 | 78 | - **386 automated tests**: Unit, integration, workflow, and health tests | |
| @@ -98,6 +99,7 @@ Near-term work. No timelines because we ship when it's ready. | |||
| 98 | 99 | - **Sale and follower notifications** (email alerts for creators) | |
| 99 | 100 | - **Contacts dashboard** (view fans who shared their email at purchase) | |
| 100 | 101 | - **Malware scanning** on upload (ClamAV + VirusTotal hash lookup) | |
| 102 | + | - **Admin CLI expansion**: User suspension/unsuspension, appeal processing, broadcast sending, revenue/transaction reports, data export triggers, storage usage audit | |
| 101 | 103 | ||
| 102 | 104 | --- | |
| 103 | 105 |
| @@ -29,7 +29,7 @@ | |||
| 29 | 29 | <li><strong>Upload content</strong> -- audio, video, text, or streams</li> | |
| 30 | 30 | <li><strong>Organize</strong> using hierarchical tags and projects</li> | |
| 31 | 31 | <li><strong>Set pricing</strong> -- free, pay-what-you-want, fixed price, or subscription</li> | |
| 32 | - | <li><strong>Get paid</strong> -- 100% of fan payments go to you</li> | |
| 32 | + | <li><strong>Get paid</strong> -- 0% platform fee, only Stripe processing</li> | |
| 33 | 33 | </ol> | |
| 34 | 34 | ||
| 35 | 35 | <h2>For Fans</h2> | |
| @@ -60,7 +60,7 @@ Creator withdraws on their schedule</div> | |||
| 60 | 60 | ||
| 61 | 61 | <h2>The Model</h2> | |
| 62 | 62 | ||
| 63 | - | <p>You pay a monthly subscription based on content type ($10-40). Your fan revenue is yours -- 100% minus payment processing (~3% from Stripe).</p> | |
| 63 | + | <p>You pay a monthly subscription based on content type ($10-40). We take 0% of your fan revenue -- the only deduction is payment processing (~3% from Stripe).</p> | |
| 64 | 64 | ||
| 65 | 65 | <p>We're funded by subscriptions, not by your success. No ads, no percentage cuts, no hidden fees.</p> | |
| 66 | 66 | ||
| @@ -166,7 +166,7 @@ Creator withdraws on their schedule</div> | |||
| 166 | 166 | <li>Permanent content links (<code>/i/UUID</code>)</li> | |
| 167 | 167 | <li>Sales and play count tracking</li> | |
| 168 | 168 | <li>Project and transaction data export</li> | |
| 169 | - | <li>Direct fan payments (you keep 100%)</li> | |
| 169 | + | <li>Direct fan payments (0% platform fee)</li> | |
| 170 | 170 | <li>Contact sharing (opt-in at purchase)</li> | |
| 171 | 171 | <li>RSS feed generation</li> | |
| 172 | 172 | <li>License keys, discount codes, download codes</li> |
| @@ -26,11 +26,11 @@ | |||
| 26 | 26 | ||
| 27 | 27 | <div class="faq-item"> | |
| 28 | 28 | <h3>What is Makenot.work?</h3> | |
| 29 | - | <p>A platform for creators to sell content directly to fans. You keep 100% of revenue. We charge a flat subscription.</p> | |
| 29 | + | <p>A platform for creators to sell content directly to fans. 0% platform fee -- only Stripe's ~3% processing applies. We charge a flat subscription.</p> | |
| 30 | 30 | </div> | |
| 31 | 31 | ||
| 32 | 32 | <div class="faq-item"> | |
| 33 | - | <h3>How do you make money if creators keep 100%?</h3> | |
| 33 | + | <h3>How do you make money with 0% platform fee?</h3> | |
| 34 | 34 | <p>Creators pay a monthly subscription ($10-$40 based on content type). We don't take a cut of sales.</p> | |
| 35 | 35 | </div> | |
| 36 | 36 |
| @@ -24,7 +24,7 @@ | |||
| 24 | 24 | ||
| 25 | 25 | <section class="sla-guarantee"> | |
| 26 | 26 | <h2>Revenue</h2> | |
| 27 | - | <p class="sla-statement"><strong>Guarantee:</strong> 100% of fan payments reach the creator, minus only the payment processor's fee (currently Stripe, ~3%).</p> | |
| 27 | + | <p class="sla-statement"><strong>Guarantee:</strong> 0% platform fee on fan payments. The only deduction is the payment processor's fee (currently Stripe, ~3%).</p> | |
| 28 | 28 | <ul> | |
| 29 | 29 | <li>No platform percentage cut, ever.</li> | |
| 30 | 30 | <li>No transaction fees, payout fees, or skimming.</li> |
| @@ -30,7 +30,7 @@ | |||
| 30 | 30 | <li>Audio uploads and streaming</li> | |
| 31 | 31 | <li>Text/newsletter content (blog system, markdown editor)</li> | |
| 32 | 32 | <li>Creator subscriptions and one-time purchases</li> | |
| 33 | - | <li>100% revenue passthrough via Stripe</li> | |
| 33 | + | <li>0% platform fee, payments via Stripe</li> | |
| 34 | 34 | <li>Full data export</li> | |
| 35 | 35 | <li>Basic analytics</li> | |
| 36 | 36 | <li>Hierarchical tagging and search</li> | |
| @@ -162,7 +162,7 @@ | |||
| 162 | 162 | <tr> | |
| 163 | 163 | <td>Direct (our platform)</td> | |
| 164 | 164 | <td>Live</td> | |
| 165 | - | <td>Full control, 100% revenue</td> | |
| 165 | + | <td>Full control, 0% platform fee</td> | |
| 166 | 166 | </tr> | |
| 167 | 167 | <tr> | |
| 168 | 168 | <td>DSP (Spotify, Apple, etc.)</td> |
| @@ -56,7 +56,7 @@ | |||
| 56 | 56 | <p>You retain all rights to content you upload. By uploading, you grant us a license to host, display, and distribute your content as necessary to operate the service.</p> | |
| 57 | 57 | ||
| 58 | 58 | <h3>Revenue</h3> | |
| 59 | - | <p>You receive 100% of fan payments. Payment processing fees (Stripe) are deducted before funds reach you. We make money from your subscription, not your sales.</p> | |
| 59 | + | <p>We charge 0% platform fee on fan payments. Payment processing fees (Stripe, ~3%) are deducted before funds reach you. We make money from your subscription, not your sales.</p> | |
| 60 | 60 | ||
| 61 | 61 | <h3>Prohibited Content</h3> | |
| 62 | 62 | <p>Don't upload:</p> |
| @@ -32,7 +32,7 @@ You're responsible for your account credentials. Enable two-factor authenticatio | |||
| 32 | 32 | You retain all rights to content you upload. By uploading, you grant us a license to host, display, and distribute your content as necessary to operate the service. | |
| 33 | 33 | ||
| 34 | 34 | ### Revenue | |
| 35 | - | You receive 100% of fan payments. Payment processing fees (Stripe) are deducted before funds reach you. We make money from your subscription, not your sales. | |
| 35 | + | We charge 0% platform fee on fan payments. Payment processing fees (Stripe, ~3%) are deducted before funds reach you. We make money from your subscription, not your sales. | |
| 36 | 36 | ||
| 37 | 37 | ### Prohibited Content | |
| 38 | 38 | Don't upload: |
| @@ -5,9 +5,9 @@ Quick answers to common questions. | |||
| 5 | 5 | ## General | |
| 6 | 6 | ||
| 7 | 7 | ### What is Makenot.work? | |
| 8 | - | A platform for creators to sell content directly to fans. You keep 100% of revenue. We charge a flat subscription. | |
| 8 | + | A platform for creators to sell content directly to fans. 0% platform fee — only Stripe's ~3% processing applies. We charge a flat subscription. | |
| 9 | 9 | ||
| 10 | - | ### How do you make money if creators keep 100%? | |
| 10 | + | ### How do you make money with 0% platform fee? | |
| 11 | 11 | Creators pay a monthly subscription ($10-$40 based on content type). We don't take a cut of sales. | |
| 12 | 12 | ||
| 13 | 13 | ### Is it really free for fans? |
| @@ -6,7 +6,7 @@ When you support creators on Makenot.work, your money actually reaches them. | |||
| 6 | 6 | ||
| 7 | 7 | 1. You pay for content or subscription | |
| 8 | 8 | 2. Payment goes directly to creator's account | |
| 9 | - | 3. Creator receives 100% (minus payment processing) | |
| 9 | + | 3. Creator receives payment (0% platform fee, only ~3% processing) | |
| 10 | 10 | 4. We make money from creator subscriptions, not your purchases | |
| 11 | 11 | ||
| 12 | 12 | ## Ways to Support |
| @@ -20,7 +20,7 @@ For writers, bloggers, journalists, newsletter creators, and anyone whose primar | |||
| 20 | 20 | - One-time purchases for individual pieces | |
| 21 | 21 | - Pay-what-you-want pricing option | |
| 22 | 22 | - Subscription tiers you define | |
| 23 | - | - **100% of fan payments** (minus ~3% payment processing) | |
| 23 | + | - **0% platform fee** on fan payments (only ~3% payment processing) | |
| 24 | 24 | ||
| 25 | 25 | ### Audience Tools | |
| 26 | 26 | - Subscriber management |
| @@ -35,7 +35,7 @@ For video creators, filmmakers, educators, and anyone producing large content fo | |||
| 35 | 35 | - One-time purchases per video | |
| 36 | 36 | - Pay-what-you-want pricing | |
| 37 | 37 | - Subscription tiers you define | |
| 38 | - | - **100% of fan payments** (minus ~3% payment processing) | |
| 38 | + | - **0% platform fee** on fan payments (only ~3% payment processing) | |
| 39 | 39 | ||
| 40 | 40 | ### Your Page | |
| 41 | 41 | - Custom profile at `/u/yourname` |
| @@ -46,7 +46,7 @@ For musicians, podcasters, indie developers, plugin makers, and anyone distribut | |||
| 46 | 46 | - Per-track or per-album purchases | |
| 47 | 47 | - Pay-what-you-want pricing | |
| 48 | 48 | - Subscription tiers you define | |
| 49 | - | - **100% of fan payments** (minus ~3% payment processing) | |
| 49 | + | - **0% platform fee** on fan payments (only ~3% payment processing) | |
| 50 | 50 | ||
| 51 | 51 | ### Your Page | |
| 52 | 52 | - Custom profile at `/u/yourname` |
| @@ -42,7 +42,7 @@ For live streamers, broadcasters, and creators who need real-time video delivery | |||
| 42 | 42 | - Tips/donations during streams | |
| 43 | 43 | - Pay-per-view live events | |
| 44 | 44 | - Subscription tiers you define | |
| 45 | - | - **100% of fan payments** (minus ~3% payment processing) | |
| 45 | + | - **0% platform fee** on fan payments (only ~3% payment processing) | |
| 46 | 46 | ||
| 47 | 47 | ### Your Page | |
| 48 | 48 | - Custom profile at `/u/yourname` |
| @@ -50,8 +50,8 @@ See [Economics](../business/economics.md) for the breakdown. | |||
| 50 | 50 | - No external managed service dependency | |
| 51 | 51 | ||
| 52 | 52 | ### Stripe | |
| 53 | - | - Standard Connect (creators own their accounts) | |
| 54 | - | - Env: STRIPE_SECRET_KEY, STRIPE_CLIENT_ID, STRIPE_WEBHOOK_SECRET | |
| 53 | + | - Express Connect (creators onboard via Account Links) | |
| 54 | + | - Env: STRIPE_SECRET_KEY, STRIPE_WEBHOOK_SECRET | |
| 55 | 55 | - Requirements: verified business, bank account for platform fees | |
| 56 | 56 | - Webhook events: checkout.session.completed, account.updated | |
| 57 | 57 | - Exit: creators keep their Stripe accounts, migrate to backup processor |
| @@ -12,9 +12,8 @@ JWT_SECRET=your-super-secret-jwt-key-change-in-production | |||
| 12 | 12 | SESSION_SECRET=your-session-secret-change-in-production | |
| 13 | 13 | ||
| 14 | 14 | # Optional: Stripe Connect (payments) | |
| 15 | - | # Get these from https://dashboard.stripe.com/settings/connect | |
| 15 | + | # Get these from https://dashboard.stripe.com/apikeys | |
| 16 | 16 | # STRIPE_SECRET_KEY=sk_test_... | |
| 17 | - | # STRIPE_CLIENT_ID=ca_... | |
| 18 | 17 | # STRIPE_WEBHOOK_SECRET=whsec_... | |
| 19 | 18 | # HOST_URL=http://localhost:3000 | |
| 20 | 19 |
| @@ -78,12 +78,56 @@ dependencies = [ | |||
| 78 | 78 | ] | |
| 79 | 79 | ||
| 80 | 80 | [[package]] | |
| 81 | + | name = "anstream" | |
| 82 | + | version = "0.6.21" | |
| 83 | + | source = "registry+https://github.com/rust-lang/crates.io-index" | |
| 84 | + | checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" | |
| 85 | + | dependencies = [ | |
| 86 | + | "anstyle", | |
| 87 | + | "anstyle-parse", | |
| 88 | + | "anstyle-query", | |
| 89 | + | "anstyle-wincon", | |
| 90 | + | "colorchoice", | |
| 91 | + | "is_terminal_polyfill", | |
| 92 | + | "utf8parse", | |
| 93 | + | ] | |
| 94 | + | ||
| 95 | + | [[package]] | |
| 81 | 96 | name = "anstyle" | |
| 82 | 97 | version = "1.0.13" | |
| 83 | 98 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
| 84 | 99 | checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" | |
| 85 | 100 | ||
| 86 | 101 | [[package]] | |
| 102 | + | name = "anstyle-parse" | |
| 103 | + | version = "0.2.7" | |
| 104 | + | source = "registry+https://github.com/rust-lang/crates.io-index" | |
| 105 | + | checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" | |
| 106 | + | dependencies = [ | |
| 107 | + | "utf8parse", | |
| 108 | + | ] | |
| 109 | + | ||
| 110 | + | [[package]] | |
| 111 | + | name = "anstyle-query" | |
| 112 | + | version = "1.1.5" | |
| 113 | + | source = "registry+https://github.com/rust-lang/crates.io-index" | |
| 114 | + | checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" | |
| 115 | + | dependencies = [ | |
| 116 | + | "windows-sys 0.61.2", | |
| 117 | + | ] | |
| 118 | + | ||
| 119 | + | [[package]] | |
| 120 | + | name = "anstyle-wincon" | |
| 121 | + | version = "3.0.11" | |
| 122 | + | source = "registry+https://github.com/rust-lang/crates.io-index" | |
| 123 | + | checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" | |
| 124 | + | dependencies = [ | |
| 125 | + | "anstyle", | |
| 126 | + | "once_cell_polyfill", | |
| 127 | + | "windows-sys 0.61.2", | |
| 128 | + | ] | |
| 129 | + | ||
| 130 | + | [[package]] | |
| 87 | 131 | name = "anyhow" | |
| 88 | 132 | version = "1.0.101" | |
| 89 | 133 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
| @@ -1190,6 +1234,46 @@ dependencies = [ | |||
| 1190 | 1234 | ] | |
| 1191 | 1235 | ||
| 1192 | 1236 | [[package]] | |
| 1237 | + | name = "clap" | |
| 1238 | + | version = "4.5.60" | |
| 1239 | + | source = "registry+https://github.com/rust-lang/crates.io-index" | |
| 1240 | + | checksum = "2797f34da339ce31042b27d23607e051786132987f595b02ba4f6a6dffb7030a" | |
| 1241 | + | dependencies = [ | |
| 1242 | + | "clap_builder", | |
| 1243 | + | "clap_derive", | |
| 1244 | + | ] | |
| 1245 | + | ||
| 1246 | + | [[package]] | |
| 1247 | + | name = "clap_builder" | |
| 1248 | + | version = "4.5.60" | |
| 1249 | + | source = "registry+https://github.com/rust-lang/crates.io-index" | |
| 1250 | + | checksum = "24a241312cea5059b13574bb9b3861cabf758b879c15190b37b6d6fd63ab6876" | |
| 1251 | + | dependencies = [ | |
| 1252 | + | "anstream", | |
| 1253 | + | "anstyle", | |
| 1254 | + | "clap_lex", | |
| 1255 | + | "strsim", | |
| 1256 | + | ] | |
| 1257 | + | ||
| 1258 | + | [[package]] | |
| 1259 | + | name = "clap_derive" | |
| 1260 | + | version = "4.5.55" | |
| 1261 | + | source = "registry+https://github.com/rust-lang/crates.io-index" | |
| 1262 | + | checksum = "a92793da1a46a5f2a02a6f4c46c6496b28c43638adea8306fcb0caa1634f24e5" | |
| 1263 | + | dependencies = [ | |
| 1264 | + | "heck", | |
| 1265 | + | "proc-macro2", | |
| 1266 | + | "quote", | |
| 1267 | + | "syn 2.0.114", | |
| 1268 | + | ] | |
| 1269 | + | ||
| 1270 | + | [[package]] | |
| 1271 | + | name = "clap_lex" | |
| 1272 | + | version = "1.0.0" | |
| 1273 | + | source = "registry+https://github.com/rust-lang/crates.io-index" | |
| 1274 | + | checksum = "3a822ea5bc7590f9d40f1ba12c0dc3c2760f3482c6984db1573ad11031420831" | |
| 1275 | + | ||
| 1276 | + | [[package]] | |
| 1193 | 1277 | name = "cmake" | |
| 1194 | 1278 | version = "0.1.57" | |
| 1195 | 1279 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
| @@ -1208,6 +1292,12 @@ dependencies = [ | |||
| 1208 | 1292 | ] | |
| 1209 | 1293 | ||
| 1210 | 1294 | [[package]] | |
| 1295 | + | name = "colorchoice" | |
| 1296 | + | version = "1.0.4" | |
| 1297 | + | source = "registry+https://github.com/rust-lang/crates.io-index" | |
| 1298 | + | checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" | |
| 1299 | + | ||
| 1300 | + | [[package]] | |
| 1211 | 1301 | name = "concurrent-queue" | |
| 1212 | 1302 | version = "2.5.0" | |
| 1213 | 1303 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
| @@ -3063,6 +3153,12 @@ dependencies = [ | |||
| 3063 | 3153 | ] | |
| 3064 | 3154 | ||
| 3065 | 3155 | [[package]] | |
| 3156 | + | name = "is_terminal_polyfill" | |
| 3157 | + | version = "1.70.2" | |
| 3158 | + | source = "registry+https://github.com/rust-lang/crates.io-index" | |
| 3159 | + | checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" | |
| 3160 | + | ||
| 3161 | + | [[package]] | |
| 3066 | 3162 | name = "itertools" | |
| 3067 | 3163 | version = "0.14.0" | |
| 3068 | 3164 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
| @@ -3357,7 +3453,7 @@ dependencies = [ | |||
| 3357 | 3453 | ||
| 3358 | 3454 | [[package]] | |
| 3359 | 3455 | name = "makenotwork" | |
| 3360 | - | version = "0.1.0" | |
| 3456 | + | version = "0.1.4" | |
| 3361 | 3457 | dependencies = [ | |
| 3362 | 3458 | "ammonia", | |
| 3363 | 3459 | "anyhow", | |
| @@ -3371,6 +3467,7 @@ dependencies = [ | |||
| 3371 | 3467 | "axum-extra", | |
| 3372 | 3468 | "base64 0.22.1", | |
| 3373 | 3469 | "chrono", | |
| 3470 | + | "clap", | |
| 3374 | 3471 | "dotenvy", | |
| 3375 | 3472 | "git2", | |
| 3376 | 3473 | "goblin", | |
| @@ -3901,6 +3998,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | |||
| 3901 | 3998 | checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" | |
| 3902 | 3999 | ||
| 3903 | 4000 | [[package]] | |
| 4001 | + | name = "once_cell_polyfill" | |
| 4002 | + | version = "1.70.2" | |
| 4003 | + | source = "registry+https://github.com/rust-lang/crates.io-index" | |
| 4004 | + | checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" | |
| 4005 | + | ||
| 4006 | + | [[package]] | |
| 3904 | 4007 | name = "openssl" | |
| 3905 | 4008 | version = "0.10.75" | |
| 3906 | 4009 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
| @@ -6526,6 +6629,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | |||
| 6526 | 6629 | checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" | |
| 6527 | 6630 | ||
| 6528 | 6631 | [[package]] | |
| 6632 | + | name = "utf8parse" | |
| 6633 | + | version = "0.2.2" | |
| 6634 | + | source = "registry+https://github.com/rust-lang/crates.io-index" | |
| 6635 | + | checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" | |
| 6636 | + | ||
| 6637 | + | [[package]] | |
| 6529 | 6638 | name = "uuid" | |
| 6530 | 6639 | version = "0.8.2" | |
| 6531 | 6640 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| @@ -1,6 +1,6 @@ | |||
| 1 | 1 | [package] | |
| 2 | 2 | name = "makenotwork" | |
| 3 | - | version = "0.1.0" | |
| 3 | + | version = "0.1.4" | |
| 4 | 4 | edition = "2024" | |
| 5 | 5 | license-file = "../../LICENSE" | |
| 6 | 6 | ||
| @@ -65,6 +65,9 @@ goblin = "0.10" | |||
| 65 | 65 | zip = "8.2" | |
| 66 | 66 | yara-x = "1.13" | |
| 67 | 67 | ||
| 68 | + | # CLI | |
| 69 | + | clap = { version = "4", features = ["derive"] } | |
| 70 | + | ||
| 68 | 71 | # Error handling | |
| 69 | 72 | thiserror = "2.0.18" | |
| 70 | 73 | anyhow = "1.0.101" | |
| @@ -93,6 +96,10 @@ url = "2.5.8" | |||
| 93 | 96 | # Error tracking | |
| 94 | 97 | sentry = { version = "0.38", default-features = false, features = ["backtrace", "contexts", "panic", "tracing", "reqwest", "rustls"] } | |
| 95 | 98 | ||
| 99 | + | [[bin]] | |
| 100 | + | name = "mnw-admin" | |
| 101 | + | path = "src/bin/mnw-admin.rs" | |
| 102 | + | ||
| 96 | 103 | [dev-dependencies] | |
| 97 | 104 | tower = { version = "0.5.3", features = ["util"] } | |
| 98 | 105 | http-body-util = "0.1" |
| @@ -0,0 +1,15 @@ | |||
| 1 | + | -- SyncKit blob storage: tracks uploaded file blobs per app/user. | |
| 2 | + | -- Blobs live in a separate S3 bucket, keyed by content hash for dedup. | |
| 3 | + | ||
| 4 | + | CREATE TABLE sync_blobs ( | |
| 5 | + | id UUID PRIMARY KEY DEFAULT gen_random_uuid(), | |
| 6 | + | app_id UUID NOT NULL REFERENCES sync_apps(id) ON DELETE CASCADE, | |
| 7 | + | user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE, | |
| 8 | + | hash TEXT NOT NULL, | |
| 9 | + | s3_key TEXT NOT NULL, | |
| 10 | + | size_bytes BIGINT NOT NULL, | |
| 11 | + | uploaded_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), | |
| 12 | + | UNIQUE(app_id, user_id, hash) | |
| 13 | + | ); | |
| 14 | + | ||
| 15 | + | CREATE INDEX idx_sync_blobs_lookup ON sync_blobs(app_id, user_id, hash); |