max / makenotwork
- Co-Authored-By
- Claude Opus 5 (1M context) <noreply@anthropic.com>
13 files changed,
+573 insertions,
-190 deletions
| @@ -10980,13 +10980,6 @@ | |||
| 10980 | 10980 | margin-top: var(--gap-section); | |
| 10981 | 10981 | } | |
| 10982 | 10982 | ||
| 10983 | - | .item-sales-tab-header { | |
| 10984 | - | display: flex; | |
| 10985 | - | justify-content: space-between; | |
| 10986 | - | align-items: center; | |
| 10987 | - | margin-bottom: var(--gap-section); | |
| 10988 | - | } | |
| 10989 | - | .item-sales-tab-header h2 { margin: 0; } | |
| 10990 | 10983 | .item-overview-embed { | |
| 10991 | 10984 | margin-top: var(--gap-pane); | |
| 10992 | 10985 | } |
| @@ -66,7 +66,20 @@ | |||
| 66 | 66 | /// progress: the seal counts template source, so deduplicating two templates | |
| 67 | 67 | /// lowers it without describing anything. The surviving site is still blocked | |
| 68 | 68 | /// on the `closest .link-row` target above. | |
| 69 | - | const HIGH_WATER: usize = 46; | |
| 69 | + | /// 44 on 2026-08-26, and this one was late: the six-panel tier-1 batch | |
| 70 | + | /// (`16d8cac4`..`14254786`) deleted `tabs/project_members.html` and | |
| 71 | + | /// `tabs/user_projects.html`, each carrying one, and nobody lowered the number. | |
| 72 | + | /// The batch ran lib tests only, and this seal is an integration-directory test, | |
| 73 | + | /// so it went unread until the suite ran on astra. Same shape as the globals | |
| 74 | + | /// seal in `8ed9ad79`, and the same lesson: a ratchet nobody runs is not a | |
| 75 | + | /// ratchet. Both are now `Act::confirm` -- "Remove {name} from this project?" in | |
| 76 | + | /// `crate::quasi::project_members` and the delete confirm in | |
| 77 | + | /// `crate::quasi::user_projects`. | |
| 78 | + | /// | |
| 79 | + | /// 43 on 2026-08-26, `b25dd957`: `tabs/item_sales.html` is described as | |
| 80 | + | /// `crate::quasi::item_sales`, and its Refund button's "Issue a full refund for | |
| 81 | + | /// {amount}? This cannot be undone." is `Act::confirm` with `Tone::Danger`. | |
| 82 | + | const HIGH_WATER: usize = 43; | |
| 70 | 83 | ||
| 71 | 84 | /// Every template, recursively. Walked rather than listed for the reason the | |
| 72 | 85 | /// frontend-globals seal walks `frontend/src`: a fence that has to be told about |
| @@ -20,6 +20,7 @@ | |||
| 20 | 20 | pub mod fan_ops; | |
| 21 | 21 | /// The MNW event vocabulary the webhook dispatcher reasons in. | |
| 22 | 22 | pub mod mnw_event; | |
| 23 | + | pub mod refund; | |
| 23 | 24 | pub mod synckit_app_pricing; | |
| 24 | 25 | pub mod synckit_billing; | |
| 25 | 26 | mod webhooks; |
| @@ -43,6 +43,7 @@ | |||
| 43 | 43 | pub mod embeds; | |
| 44 | 44 | pub mod export_act; | |
| 45 | 45 | pub mod forum_memberships; | |
| 46 | + | pub mod item_sales; | |
| 46 | 47 | pub mod item_tabs; | |
| 47 | 48 | pub mod library_contacts; | |
| 48 | 49 | pub mod library_tabs; | |
| @@ -324,6 +325,13 @@ | |||
| 324 | 325 | project_members::NEST, | |
| 325 | 326 | writes_only(app, project_members::WRITES, project_members::renderer), | |
| 326 | 327 | ), | |
| 328 | + | // The item dashboard's Sales panel: a parameterized read address, so | |
| 329 | + | // the read stays on Askama and only the Refund write is described. | |
| 330 | + | // `b25dd957`; see `writes_only`. | |
| 331 | + | ( | |
| 332 | + | item_sales::NEST, | |
| 333 | + | writes_only(app, item_sales::WRITES, item_sales::renderer), | |
| 334 | + | ), | |
| 327 | 335 | ( | |
| 328 | 336 | forum_memberships::SETTINGS_PATH, | |
| 329 | 337 | mount( |
| @@ -271,7 +271,6 @@ | |||
| 271 | 271 | ItemDetailsTabTemplate, | |
| 272 | 272 | ItemPricingTabTemplate, | |
| 273 | 273 | ItemFilesTabTemplate, | |
| 274 | - | ItemSalesTabTemplate, | |
| 275 | 274 | ItemEmbedTabTemplate, | |
| 276 | 275 | // Onboarding checklist | |
| 277 | 276 | OnboardingChecklistPartialTemplate, |
| @@ -9,8 +9,8 @@ | |||
| 9 | 9 | AdminAppealRow, AdminHeldUploadRow, AdminReportRow, AdminUserRow, AdminWaitlistRow, | |
| 10 | 10 | BlogPostDashboardRow, ChartBar, Collection, ContentItem, DiscoverItem, DiscoverProject, | |
| 11 | 11 | InviteCodeDisplay, Item, ItemSection, LicenseKeyRow, Project, ProjectCard, ProjectMemberRow, | |
| 12 | - | PromoCodeRow, SaleRow, SidebarView, StatCard, SubscriptionTier, SyncAppRow, TipReceived, | |
| 13 | - | Transaction, User, UserSubscription, Version, WaitlistEntry, WaveStats, | |
| 12 | + | PromoCodeRow, SidebarView, StatCard, SubscriptionTier, SyncAppRow, TipReceived, Transaction, | |
| 13 | + | User, UserSubscription, Version, WaitlistEntry, WaveStats, | |
| 14 | 14 | }; | |
| 15 | 15 | ||
| 16 | 16 | use super::CsrfTokenOption; | |
| @@ -914,18 +914,6 @@ | |||
| 914 | 914 | pub versions: Vec<Version>, | |
| 915 | 915 | } | |
| 916 | 916 | ||
| 917 | - | /// Item sales tab: transaction history with refund actions. | |
| 918 | - | #[derive(Template)] | |
| 919 | - | #[template(path = "partials/tabs/item_sales.html")] | |
| 920 | - | pub struct ItemSalesTabTemplate { | |
| 921 | - | pub item: Item, | |
| 922 | - | pub sales: Vec<SaleRow>, | |
| 923 | - | /// Where the described Export control posts. Built by the handler rather | |
| 924 | - | /// than composed in the template: `export_act::html` takes a `&str` and | |
| 925 | - | /// Askama cannot `format!` one in an expression. | |
| 926 | - | pub export_route: String, | |
| 927 | - | } | |
| 928 | - | ||
| 929 | 917 | /// Item embed tab: copy-paste embed codes for this item. | |
| 930 | 918 | #[derive(Template)] | |
| 931 | 919 | #[template(path = "partials/tabs/item_embed.html")] |