Files
cannamanage/docs/sprint-14/cannamanage-sprint14-analysis.md
T
Patrick Plate dad798a904
Deploy to TrueNAS / deploy (push) Failing after 33s
feat: Sprint 14 — Marketing & Monetization
- Landing page with hero, feature grid, trust signals
- Split-layout login redesign (admin + portal)
- Pricing page with storage tiers (5GB/50GB/unlimited)
- StorageQuotaService backend (V36 migration, 402 on exceeded)
- Frontend storage integration + 402 error handling
- StorageController uses TenantContext for tenant isolation
- onTierChange() hook for subscription tier updates
2026-06-18 20:28:35 +02:00

7.2 KiB

Analysis: Sprint 14 — Marketing & Monetization

Date: 2026-06-18 Author: Patrick Plate / Lumen (Planner) Status: v1 Sprint Theme: Marketing & Monetization


1. Problem Analysis

CannaManage is production-ready after Sprint 13's hardening. However, the public-facing marketing surfaces are minimal — there is no landing page (the root / currently serves the pricing page directly via the marketing layout), the login pages use a basic centered-card layout that doesn't communicate product value, and the pricing page lacks storage quota information which is a core monetization lever.

Additionally, the backend has no concept of storage quotas per tenant. Documents can be uploaded without limit, creating an unbounded cost liability on the file storage (TrueNAS/disk). Sprint 14 introduces a StorageQuotaService that enforces per-plan limits, making the pricing tiers meaningful at the infrastructure level.

Sprint Goals

  1. Landing Page — Create a professional homepage that converts visitors to signups
  2. Login Redesign — Split-layout login pages that reinforce brand value during auth flow
  3. Pricing Rework — Add storage tier information, update pricing model
  4. Storage Quota Backend — Enforce plan-based storage limits on document uploads

2. Affected Components

Component Path Role
Marketing layout cannamanage-frontend/src/app/(marketing)/layout.tsx Shared header/footer for marketing pages
Homepage (NEW) cannamanage-frontend/src/app/(marketing)/page.tsx Landing page — hero, features, trust signals
Pricing page cannamanage-frontend/src/app/(marketing)/pricing/page.tsx Pricing cards with storage tiers
Auth layout cannamanage-frontend/src/app/(auth)/layout.tsx Centered flex container for login
Admin login cannamanage-frontend/src/app/(auth)/login/page.tsx Admin/staff login form
Portal login cannamanage-frontend/src/app/(portal)/portal-login/page.tsx Member portal login form
PlanTier enum cannamanage-domain/src/main/java/de/cannamanage/domain/enums/PlanTier.java TRIAL, STARTER, PRO, ENTERPRISE
Club entity cannamanage-domain/src/main/java/de/cannamanage/domain/entity/Club.java Needs storageUsedBytes field
Document entity cannamanage-domain/src/main/java/de/cannamanage/domain/entity/Document.java Has fileSize field — source of truth for usage
DocumentService cannamanage-service/src/main/java/de/cannamanage/service/DocumentService.java Upload logic — needs quota check
StorageQuotaService (NEW) cannamanage-service/src/main/java/de/cannamanage/service/StorageQuotaService.java Quota calculation and enforcement
StorageController (NEW) cannamanage-api/src/main/java/de/cannamanage/api/controller/StorageController.java REST endpoint for storage usage
Flyway V36 (NEW) cannamanage-api/src/main/resources/db/migration/V36__storage_quota.sql Add storage tracking column
i18n messages cannamanage-frontend/src/messages/de.json New keys for landing page, pricing storage
Documents frontend service cannamanage-frontend/src/services/documents.ts Needs quota-exceeded error handling

3. Current State (Ist-Zustand)

Marketing Pages

  • No landing page exists at (marketing)/page.tsx — the root / route likely falls through or shows a 404
  • Pricing page has 3 tiers (Starter €19, Pro €49, Enterprise) with member limits and feature lists, but no storage information
  • Marketing layout has a sticky header with logo + "Preise" + "Anmelden" links, and a footer with Produkt/Rechtliches columns
  • Navigation text is hardcoded German (not i18n) in the layout

Login Pages

  • Auth layout is a minimal centered flex container: fixed inset-0 z-50 flex items-center justify-center
  • Admin login renders a centered card with logo, email/password form, forgot password link, and portal link
  • Portal login is nearly identical but uses portal-specific translations and mock auth
  • Both pages use the same visual pattern — no split-layout, no brand messaging during auth

Storage Backend

  • Document entity already tracks fileSize (Long) per file
  • PlanTier enum exists: TRIAL, STARTER, PRO, ENTERPRISE
  • No storage quota concept exists anywhere — no storage_used_bytes column, no quota checks on upload
  • DocumentService handles upload/download/delete but never checks cumulative storage
  • Latest Flyway migration: V35__generated_reports_add_timestamps.sql

4. Risk Assessment

Risk Probability Impact Mitigation
Landing page doesn't convert (poor copy/design) Medium Medium (lost signups) Follow proven SaaS landing page patterns; iterate based on analytics
Storage quota breaks existing uploads Low High (data loss) Implement as soft-limit first — warn but don't block for existing over-limit tenants
i18n key explosion Low Low (maintenance) Group new keys under marketing.home, marketing.pricing.storage namespaces
Split login layout breaks on mobile Medium Medium (can't log in) Mobile-first design: left panel hidden on <md breakpoints
Quota calculation performance (SUM query) Low Medium (slow uploads) Cache quota in storage_used_bytes column; recalculate on upload/delete

5. Solution Options

  • Landing page, login redesign, pricing update, storage quota backend
  • Effort: ~16-20 hours
  • Pros: Complete marketing+monetization story, enables public launch
  • Cons: Larger scope, more testing surface

Option B: Frontend Only — Landing + Login + Pricing (No Backend)

  • Skip StorageQuotaService, just update frontend
  • Effort: ~8-10 hours
  • Pros: Faster delivery, lower risk
  • Cons: Storage limits are marketing fiction without enforcement

Option C: Backend Only — Storage Quota (No Marketing)

  • Implement quota enforcement, defer marketing pages
  • Effort: ~6-8 hours
  • Pros: Real monetization enforcement
  • Cons: No user-facing marketing value, can't launch publicly

6. Recommendation

Option A — the full sprint. The four areas are interdependent: the pricing page promises storage limits that the backend must enforce, and the landing page is the entry point that drives users to pricing. Login redesign is a low-risk polish pass that significantly improves first impressions.

The storage quota backend should be designed as an incremental counter (update storage_used_bytes on upload/delete) rather than a SUM query on every upload — this keeps upload latency constant regardless of document count.


7. Open Questions

  • Should the landing page include a product screenshot/mockup, or is an illustration-based hero preferred?
  • For portal login left panel: show rotating testimonials, or static feature highlights?
  • Storage overage billing (€0.15/GB/mo for Pro) — is this just displayed in pricing, or should we build the actual billing integration now?
  • Free trial — is TRIAL tier (PlanTier enum already has it) time-limited? Should landing page mention trial duration?