- type
- concept
- created
- Tue Apr 07 2026 02:00:00 GMT+0200 (Central European Summer Time)
- updated
- Tue Apr 07 2026 02:00:00 GMT+0200 (Central European Summer Time)
- sources
- raw/articles/PRD
- tags
- newsletter email buyer-engagement output-layer
Newsletter Generation
Overview
In the MVP, buyers do not have a self-service web portal. The personalized newsletter IS the buyer's view into the marketplace. Each newsletter is generated per-buyer, filtered through geographic visibility rules, and organized into sections by match quality. The newsletter is generated by Celery beat tasks and sent via email with tracking for delivery, opens, clicks, and bounces.
Newsletter Sections
Each newsletter contains up to four sections:
1. Exact Matches (score >= 90)
Full details for each item: paper type, GSM, width, quantity, grade, price (adjusted for buyer's region), mill trust score, surplus source. CTA buttons: "View Details" and "I'm Interested." Includes an exclusivity badge with countdown timer if the buyer has an active exclusivity window.
2. Container Proposals
If the buyer has matched surplus from multiple sources that can be combined, the newsletter shows proposed containers. Each proposal includes: item count, total weight, container utilization percentage, total value, and a freight comparison showing combined container freight vs. individual lot shipping costs. CTA buttons: "View Proposal" and "Accept Container." See wiki/concepts/container-assembly.
3. Close Matches (score 70-89)
Compact list with fewer details. CTA: "View All Close Matches."
4. Coming Soon (pre-production items)
Future availability with estimated dates, for items where is_pre_production = true. CTA: "Express Interest." See wiki/concepts/pre-production-announcements.
Personalization Rules
| Element | Personalization |
|---|---|
| Subject line | Includes buyer name and top match: "Carlos, 5 Kraftliner lots match your specs" |
| Greeting | "Hi {buyer.contact_name}" |
| Match content | Only items matching buyer's active BuyerSpecs |
| Visibility filter | Only items buyer is allowed to see per geographic rules |
| Price display | Adjusted for buyer's region (base price + geographic adjustment) |
| Freight estimate | Based on buyer's delivery port or city |
| Currency | Displayed in buyer's preferred currency |
| Language | English in V1; multilingual planned for V2+ |
Delivery Schedule
| Frequency | Trigger | Min Items | Max Items |
|---|---|---|---|
daily |
Celery beat at 08:00 UTC | 3 | 20 |
weekly |
Celery beat Monday 08:00 UTC | 3 | 50 |
on_match |
New match with score >= 80 | 1 | 10 |
exclusivity |
Exclusivity granted (always immediate) | 1 | 1 |
Key rules:
- Minimum 3 matches required to send a regular newsletter (avoids spamming with 1-item emails)
- Exception: exclusivity notifications are ALWAYS sent immediately regardless of minimum count
- If a buyer has 0 active BuyerSpecs, no newsletter is generated
- Buyers can choose their frequency: daily, weekly, or on_match
- Each newsletter links to a detail page or reply-to-purchase mechanism
Tracking and Metrics
| Metric | Implementation |
|---|---|
| Delivered | Email service delivery confirmation |
| Opened | 1x1 tracking pixel embedded in HTML |
| Clicked | Redirect URL wrapping each CTA link |
| Bounced | Email service bounce notification |
| Unsubscribed | Footer unsubscribe link sets buyer.newsletter_active = false |
The Newsletter entity stores: status (generated / sent / delivered / opened / clicked / bounced / failed), sent_at, opened_at, clicked_at, trigger (scheduled / new_match / exclusivity / manual), match_count, and container_proposal_count.
Technical Implementation
Newsletters are generated by a @shared_task in Celery:
- Query active, newsletter-subscribed buyers with the matching frequency
- For each buyer, get active matches (visibility-filtered)
- If matches < minimum threshold for the frequency, skip
- Get any pending container proposals
- Render HTML using the newsletter template (table-based layout for email client compatibility at 600px width)
- Create Newsletter record
- Queue async email send
The HTML template is designed for compatibility across Gmail, Outlook, and Apple Mail using table-based layout (not flexbox/grid).
Newsletter as Primary Interface
This is a deliberate architectural decision. In the MVP phase, the newsletter replaces what would traditionally be a web dashboard for buyers. The rationale:
- Buyers in the paper industry are accustomed to receiving offers via email
- Zero behavior change for buyers (they already process offers from email)
- Faster to build than a full web portal
- Push-based (buyer does not need to remember to check a website)
- Morichal back office handles the actual purchase flow once a buyer expresses interest
In V1+, buyers get a web portal (Angular) alongside newsletters, but the newsletter remains a core engagement channel.
Sources
- raw/articles/PRD -- sections 6.5, 11.1-11.5
Related
- wiki/concepts/matching-algorithm -- produces the matches shown in newsletters
- wiki/concepts/geographic-visibility-system -- filters which items appear per buyer
- wiki/concepts/48-hour-exclusivity-window -- exclusivity badges in newsletters
- wiki/concepts/container-assembly -- container proposals shown in newsletters
- wiki/concepts/pre-production-announcements -- "Coming Soon" section