/ REMP integrace Interní dokument

03 — Implementační plán

Předpoklady

  • Start: 21. července 2026
  • Délka sprintu: 3 týdny
  • Fáze 1 nezahrnuje Beam tracking
  • REMP CRM, Mailer, Campaign a SSO jsou nasazeny a přístupné (produkční nebo staging prostředí)
  • Ecoidentita SSO redirect + userinfo flow je funkční alespoň ve staging
  • REMP CRM je SoT pro produkty, předplatné a platby (FatChilli)

Fáze přehled

FázeSprintNázevCíl
0S1Infrastructure & FoundationsREMP klienty, config, CI, dev prostředí
1S1–S2Identity & User SyncEcoidentita → Folio → REMP CRM user provisioning
2S2–S3Entitlement & Paywall CacheEntitlement check z CRM, cache, webhook handling
3S3–S4Paywall UI & Content LockingFrontend paywall rendering, PaywallTag → entitlement
4S4–S5Campaign Integrationremplib.js, showtime, segment-based banners
5S5–S6Mailer IntegrationNewsletter authoring handoff, Mailer jobs, digest assembly
6S6–S7E2E Testing & HardeningIntegration tests, monitoring, SLA, go-live prep

Detailní plán

Fáze 0: Infrastructure & Foundations (Sprint 1: 21.7.–8.8.)

0.1 REMP Client Library

Cíl: Vytvořit Ruby gem / Rails engine modul pro komunikaci s REMP API.

Implementace:

  • Economia::Remp::CrmClient — HTTP klient (Faraday) pro REMP CRM API
  • Economia::Remp::MailerClient — HTTP klient pro REMP Mailer API
  • Economia::Remp::CampaignClient — HTTP klient pro Campaign API
  • Economia::Remp::Configuration — Rails initializer, env vars
  • Error handling, retry logic, circuit breaker (optional)
  • Request/response logging

Třída:

# app/services/economia/remp/crm_client.rb
module Economia::Remp
  class CrmClient
    include ActiveSupport::Configurable
    
    config_accessor :base_url, :api_token, :timeout
    
    def initialize
      @connection = Faraday.new(url: base_url) do |f|
        f.request :json
        f.response :json
        f.request :authorization, 'Bearer', api_token
        f.adapter Faraday.default_adapter
      end
    end
    
    def find_user(remp_user_id)
      @connection.get("/api/v1/users/#{remp_user_id}")
    end
    
    def register_user(email:, ext_id:, **attrs)
      @connection.post("/api/v1/users/register", {
        email: email, ext_id: ext_id, **attrs
      })
    end
    
    def active_subscriptions(remp_user_id)
      @connection.get("/api/v1/users/#{remp_user_id}/subscriptions", active: true)
    end
  end
end

Story points: 5 SP Endpoints: Interní (žádné REMP API — jde o klientský kód)

0.2 Development Environment

Cíl: Docker compose nebo přístup k REMP staging.

Implementace:

  • Docker compose pro lokální REMP stack (SSO, Mailer, Campaign, CRM)
  • Nebo: VPN přístup + staging tokeny
  • Seed data pro subscription types, mail types, test uživatele
  • CI pipeline step pro integration testy

Story points: 3 SP

0.3 Database Migrations

Cíl: Přidat REMP-specifická pole do CMS modelů.

# Migration
add_column :folio_users, :remp_user_id, :integer, index: true
add_column :folio_users, :remp_synced_at, :datetime
# CMS nemá subscription model — subscriptions řeší REMP CRM

Story points: 2 SP


Fáze 1: Identity & User Sync (Sprint 1–2: 21.7.–29.8.)

1.1 User Sync on Login

Cíl: Při přihlášení přes Ecoidentita vytvořit / nalinkovat uživatele v REMP CRM.

Implementace:

  • Economia::Remp::UserSyncService#sync!(folio_user)
  • Volá REMP CRM POST /api/v1/users/register nebo PUT /api/v1/users/{id}
  • Ukládá remp_user_id do Folio::User
  • Background job Economia::Remp::SyncUserJob pro async processing
  • Deduplikace na základě ext_id (Ecoidentita user ID)

Integrace v Folio:

# V OmniAuth callback controlleru (Ecoidentita)
after_action :sync_to_remp, only: [:create]

def sync_to_remp
  Economia::Remp::SyncUserJob.perform_later(current_user.id)
end

REMP CRM endpoint: POST /api/v1/users/register REMP CRM handler: Users module — user registration

Story points: 5 SP

1.2 User Update Sync

Cíl: Při změně profilu (CMS self-care) aktualizovat REMP CRM.

Implementace:

  • ActiveRecord callback na Folio::User → async job
  • Volá PUT /api/v1/users/{remp_user_id}
  • Sync polí: email, first_name, last_name

Story points: 3 SP

1.3 Bulk User Import (Initial Migration)

Cíl: Jednorázový import existujících uživatelů z Folio/legacy do REMP CRM.

Implementace:

  • Rake task economia:remp:import_users
  • Batched processing (1000 users per batch)
  • Volá POST /api/v1/users/register (nebo bulk endpoint pokud existuje)
  • Logging a error reporting

REMP Mailer endpoint: POST /api/v1/users/bulk-user-registered

Story points: 3 SP


Fáze 2: Entitlement & Paywall Cache (Sprint 2–3: 11.8.–19.9.)

2.1 Subscription Type Mapping (konfigurace)

Cíl: CMS musí znát kódy REMP CRM subscription types pro vyhodnocení paywallu.

Implementace:

  • Config/YAML file s mapováním content_access → PaywallTag
  • FatChilli vytváří subscription types v REMP CRM
  • CMS jen čte kódy pro entitlement matching
# config/remp_subscription_types.yml
# Mapování REMP CRM subscription types na PaywallTag access levels
hn_digital_monthly:
  content_access: ["web", "premium"]
hn_digital_yearly:
  content_access: ["web", "premium"]
hn_print_digital_monthly:
  content_access: ["web", "premium", "print"]

Story points: 2 SP

2.2 Entitlement Cache Service

Cíl: CMS cachuje entitlement data z REMP CRM pro rychlé vyhodnocení paywallu.

Implementace:

  • Economia::Remp::EntitlementCache — Redis cache per user
  • Dotazuje REMP CRM GET /api/v1/users/{id}/subscriptions?active=true
  • Cache invalidation přes webhook z CRM (viz 2.4)
  • TTL z konfigurace (doporučeno 60–300s)
  • Fallback při nedostupnosti CRM → degraded mode (článek zamknutý)

REMP CRM endpoint: GET /api/v1/users/{id}/subscriptions

Story points: 5 SP

2.3 Entitlement Check Service

Cíl: Folio CMS může ověřit, zda uživatel má přístup ke článku s PaywallTag.

Implementace:

  • Economia::Paywall::EntitlementChecker#has_access?(user:, paywall_tag:)
  • Volá GET /api/v1/users/{remp_user_id}/subscriptions?active=true
  • Cachuje výsledek v Redis (TTL z konfigurace)
  • Fallback: při nedostupnosti CRM → degraded mode (článek zamknutý)

REMP CRM endpoint: GET /api/v1/users/{id}/subscriptions

Story points: 5 SP

2.4 Webhook Receiver

Cíl: CMS přijímá webhooky z REMP CRM o změnách subscription stavu.

Implementace:

  • Api::Internal::Remp::WebhooksController
  • HMAC-SHA256 verifikace
  • Invalidace entitlement cache
  • Event logging

Story points: 3 SP


Fáze 3: Paywall UI & Content Locking (Sprint 3–4: 1.9.–10.10.)

3.1 Server-Side Paywall Rendering

Cíl: Články s PaywallTag se renderují jako zamknuté pro neautorizované uživatele.

Implementace:

  • V article show controlleru: volání EntitlementChecker
  • Dva rendery: plný obsah vs. truncated + paywall lock
  • ViewComponent Economia::Article::PaywallLockComponent
  • Stimulus controller pro interaktivní paywall UI

Folio třídy:

  • Economia::ArticlesController#show — rozšíření
  • Economia::Article::PaywallTag — existující model
  • Economia::Article::PaywallLockComponent — nový ViewComponent

Story points: 8 SP

3.2 Paywall Variants

Cíl: Různé typy paywall lock UI podle kontextu (hard wall, metered, freemium).

Implementace:

  • PaywallTag.access_level → typ paywallu
  • Konfigurovatelné limity (metered: X článků zdarma)
  • Cookie/localStorage pro metered counting
  • CTA varianty (subscribe, login, trial)

Story points: 5 SP

3.3 Subscriber Content Indicators

Cíl: V listing stránkách (rubrika, homepage) zobrazit ikonu/badge pro premium obsah.

Implementace:

  • Helper paywall_badge(article) → renders badge
  • CSS styling pro premium content markers
  • Článek v listingu neodhaluje obsah

Story points: 2 SP


Fáze 4: Campaign Integration (Sprint 4–5: 13.10.–21.11.)

4.1 remplib.js Integration

Cíl: Na všech stránkách Folio CMS načíst remplib.js pro showtime.

Implementace:

  • Partial _remp_campaign.html.slim v layoutu
  • Konfigurace campaign token, URL
  • Předání proměnných z CMS (article_id, section, is_subscriber…)
  • Podmíněné načítání (ne na admin, ne na error pages)

Story points: 3 SP

4.2 Segment Provider Configuration

Cíl: Campaign musí vědět, odkud čerpat segmenty.

Implementace:

  • Konfigurace v Campaign admin: přidat CRM segment provider
  • Nebo: Beam segment provider (pokud Beam bude v budoucnu)
  • Mapování segmentů na kampaně

Story points: 2 SP

4.3 Campaign Templates for Paywall Upsell

Cíl: Vytvořit šablony bannerů pro paywall upsell, trial nabídku, login prompt.

Implementace:

  • HTML/CSS banner šablony v Campaign admin
  • A/B test varianty
  • Cílení: anonymous users, registered-non-subscribers, expired subscribers

Story points: 5 SP

4.4 Segment Cache Integration

Cíl: Real-time aktualizace segment cache pro cílení.

REMP Campaign endpoints:

  • POST /api/segment-cache/provider/{provider}/code/{code}/add-user
  • POST /api/segment-cache/provider/{provider}/code/{code}/remove-user

Implementace:

  • Při subscription change: add/remove user z segmentu “active_subscribers”
  • Background job z CMS

Story points: 3 SP


Fáze 5: Mailer Integration (Sprint 5–6: 24.11.–2.1.2027)

5.1 Mail Type Setup

Cíl: CMS zná, které existující mail_type_code v REMP Maileru se používají pro jednotlivé newsletterové use-cases.

Implementace:

  • Konfigurace / lookup tabulka newsletter type → mail_type_code
  • Admin select pro přiřazení existujícího mail_type_code
  • Koordinace s FatChilli nad provisioningem mail types v REMP
  • CMS nevlastní reader subscriptions ani Mailer mail type admin

Story points: 3 SP

5.2 Newsletter Content Authoring UI

Cíl: Redaktor připraví newsletter po obsahové stránce v CMS.

Implementace:

  • Editor / výběr článků / média / preheader / subject
  • Draft/publish workflow v CMS
  • Lokální preview email-safe HTML výstupu
  • Reader subscription management zůstává mimo CMS v REMP

Story points: 5 SP

5.3 Newsletter Template Handoff & Job Creation

Cíl: CMS předá připravený newsletter do REMP Maileru k rozeslání.

Implementace:

  • POST /api/v1/mailers/templates pro vytvoření / update template
  • GET /api/v1/mailers/render-template?code=... pro kontrolu uloženého template
  • POST /api/v2/mailers/jobs pro vytvoření odesílacího jobu
  • Uložení template_code / job_id / context do CMS pro audit a dohledatelnost

REMP Mailer handlers: MailCreateTemplateHandler, RenderTemplateApiHandler, MailJobCreateApiHandler CMS třída: Economia::Remp::NewsletterComposerService

Story points: 8 SP

5.4 Mailer Handoff Hardening

Cíl: Předání newsletteru z CMS do Maileru je bezpečné, idempotentní a dobře operovatelné.

Implementace:

  • Stabilní naming a versioning template_code / context
  • Retry strategie, chybové stavy a audit log
  • Monitoring / alerting na Mailer API handoff
  • Reader transactional emails zůstávají mimo CMS v REMP / EGO-SSO

Story points: 5 SP

5.5 Author/Section Digest Content Assembly

Cíl: CMS umí automaticky sestavit content pro digest-type newslettery, ale delivery i subscriptions zůstávají v REMP.

Implementace:

  • Sidekiq scheduled job: Economia::Remp::AuthorDigestJob
  • Sbírá články publikované za poslední týden per autor / rubriku
  • Vyrenderuje newsletter content stejně jako manuální flow
  • Předá template + job do Maileru přes stejný handoff jako v 5.3
  • Recipient list / segment ownership zůstává v REMP

Story points: 5 SP


Fáze 6: E2E Testing & Hardening (Sprint 6–7: 5.1.–13.2.2027)

6.1 Integration Tests

Cíl: End-to-end testy celého flow.

Implementace:

  • System tests (Capybara): login → paywall → subscribe → unlock
  • API tests: mock REMP responses, verify request format
  • VCR cassettes / WebMock pro unit testy
  • CI pipeline s REMP staging

Story points: 8 SP

6.2 Monitoring & Alerting

Cíl: Monitoring API komunikace, error rates, latency.

Implementace:

  • ActiveSupport::Notifications instrumentace
  • Grafana dashboard pro REMP API calls
  • Sentry error tracking pro sync failures
  • Dead letter queue pro failed sync jobs

Story points: 3 SP

6.3 Documentation & Runbook

Cíl: Provozní dokumentace, troubleshooting guide.

Implementace:

  • Runbook pro časté problémy (sync failure, cache stale, API down)
  • SLA definice: kdo řeší co, escalation path
  • API dokumentace (OpenAPI/Swagger)

Story points: 3 SP

6.4 Performance Optimization

Cíl: Optimalizace pro produkční zátěž.

Implementace:

  • Load testing entitlement check endpoint
  • Redis cache tuning
  • Connection pooling pro REMP API calls
  • Rate limiting pro webhook receiver

Story points: 3 SP


Časová osa (Gantt)

Sprint 1 (21.7.–8.8.)   ████ Fáze 0 (Infrastructure) + Fáze 1a (User Sync Login)
Sprint 2 (11.8.–29.8.)  ████ Fáze 1b (User Import) + Fáze 2a (Sub Type Mapping, Sub Sync)
Sprint 3 (1.9.–19.9.)   ████ Fáze 2b (Entitlement, Webhooks) + Fáze 3a (Paywall Rendering)
Sprint 4 (22.9.–10.10.)  ████ Fáze 3b (Paywall Variants, Badges) + Fáze 4a (remplib, Segments)
Sprint 5 (13.10.–31.10.) ████ Fáze 4b (Campaign Templates, Cache) + Fáze 5a (Mail Types, NL UI)
Sprint 6 (3.11.–21.11.)  ████ Fáze 5b (NL Job, Transactional, Digest)
Sprint 7 (24.11.–12.12.) ████ Fáze 6 (E2E Tests, Monitoring, Docs, Perf)

Buffer (15.12.–2.1.2027) ░░░░ Bug fixes, go-live prep, UAT

Celkem: 7 sprintů = 21 týdnů = ~5 měsíců (21.7.2026 – 12.12.2026) + buffer


Závislosti a rizika

ZávislostVlastníkRiziko
REMP CRM nasazení a API přístupEconomia / FatChilliBez staging CRM nelze začít fázi 1
Ecoidentita SSO fungujícíEconomiaBez Ecoidentita nelze testovat user sync
REMP CRM subscription types definiceEconomia + FatChilliCMS potřebuje znát kódy pro entitlement check
Checkout flow rozhodnutíEconomia + FatChilliCRM UI vs. CMS frontend + CRM API
Newsletter šablony a content strategyEconomia (redakce)Nelze implementovat mailer bez šablon
PaywallTag implementace (Epic 01b)SinfinMusí být hotový před fází 3