Modernization

Migration Decisions Register

Last updated: 2026-02-01 | Modernization

Migration Decisions Register

Progressive register of domain-level migration verdicts. Updated after each analysis session.

Verdict Definitions

Verdict Meaning
Migrate Build new Gen 3 service, migrate data, retire Gen 2
Consolidate Merge multiple services into fewer Gen 3 services
Upgrade Upgrade Gen 2 in-place (dependency bumps, patterns)
Retire Remove entirely — functionality no longer needed
Replace (SaaS) Replace with third-party SaaS product
Defer Insufficient evidence — revisit after further analysis

Complexity Definitions

Size Meaning
S 1-2 services, simple schema, no external integrations
M 2-4 services, moderate schema, 1-2 integrations
L 4-6 services, complex schema, multiple integrations
XL 6+ services, complex data migration, critical integrations, BPM state

Decision Register

Domain Verdict Complexity Key Constraint Dependencies Session
Frontend Consolidate XL CSS framework mismatch (Tailwind vs Bootstrap) Backend API stability (24+ GraphQL gateways) 1
User Identity Upgrade L Magic Link SPI preservation + CIB Seven EOL All 35+ services depend on Keycloak JWT 2
Content & Streaming Consolidate L Mux integration spans content + media; NFS storage coupled to GKE Mux API keys, GCS buckets, Zoom credentials 3
Payment (Billing) Upgrade L CIB Seven BPM orchestrates purchase fulfillment; Stripe webhook/product sync Stripe API keys, CIB Seven plugin, wallet, inventory, email 4
Payment (Wallet) Upgrade S Simple coin ledger; no external payment gateway Purchase-request-bpm (RabbitMQ), SSE 5
Payment (Transaction) Upgrade S Single-table payment log; no double-entry bookkeeping Inventory service (GraphQL) 5
Dwolla Retire S Inactive since Jan 2023; replaced by Stripe None — archive repos, remove dead code 5
Events (Shoutout) Consolidate M CIB Seven BPM orchestrates fulfillment; in-flight process instances must drain Mux API, FFmpeg, wallet (refunds), email, SSE, inventory 6
Events (Inventory) Upgrade M Cross-cutting product catalog hub; 36 migrations, 11+ controllers Stripe, subscriptions, shoutout, class-catalog, purchase-request-bpm 6
Events (Class-Catalog) Upgrade M 32 migrations, 15+ entities, learning credits (CEU/PDU); deprecated Arlo LMS Tags, Keycloak, SSE, email 6
Events (Onsite-Event) Upgrade S Simple check-in (2 migrations, 2 entities) None significant 6
Meet-and-Greet BPM Retire S Gen 1 Camunda 7.17, Jitsi dependency, no Gen 2 replacement None — archive repo 6
Custom Tixr Retire S Gen 1 Tixr integration, inactive None — archive repo 6
Comms (Email+SMS+Notifications) Consolidate M Mandrill library (lutung) unmaintained; shared DB; pipeline relationship Keycloak (JWT), Mandrill API keys, Twilio API keys, SSE 7
Comms (Chat) Upgrade S Thin Stream Chat wrapper; subscription-based channel access Stream Chat API keys, inventory (purchase triggers) 7
Comms (Message-Board) Upgrade S Redis SSE fanout; broadcast donation leaderboard; 5 migrations Redis, SSE, inventory (purchase state) 7
Comms (SSE) Upgrade S Platform-wide real-time infrastructure; 8 RabbitMQ handlers; Redis + PostgreSQL Redis, all publishing services (7+) 7
peeq-conference-sse Retire S Gen 1 Java 11/SB 2.4.2, meet-and-greet only, Jitsi dependency None — archive repo 7
peeq-websocket Retire S Gen 1 Node.js/Socket.IO, single EC2 SPOF, Jitsi/Puppeteer watchers None — archive repo 7
peeq-sse Retire S Gen 1 Java 11/SB 2.6.8, replaced by Gen 2 SSE None — archive repo 7
Infrastructure (GKE/Istio) Upgrade L Zonal clusters need regional HA; cluster-per-tenant is expensive All services depend on GKE + Istio routing 8
CI/CD (GitHub Actions) Upgrade S 28 reusable workflows already mature; add security enforcement All service builds depend on reusable workflows 8
Helm Charts (Common) Upgrade S Common chart v0.0.179 (33 templates) is stable foundation All 48 service charts depend on common chart 8
Terraform (IaC) Upgrade M 19 modules well-factored; add regional HA, alerting, NetworkPolicies All infrastructure provisioned via Terraform 8
Observability Upgrade M Prometheus deployed; gaps in alerting, tracing, APM, SLOs All services expose /actuator/prometheus metrics 8
peeq-logging Retire S Gen 1 Node.js/Express logging aggregator; replace with Cloud Logging or Elastic Cloud Elasticsearch + Kibana depend on this pipeline 8
peeq-shared-secret Retire S Gen 1 Java 11/SB 2.4.3; likely replaced by ArgoCD Vault Plugin + GCP Secret Manager Unclear if any services still call this 8

Hypotheses Tracker

# Hypothesis Assurance Evidence Session
H1 Broadcast functionality is not deployed to production L2 (Verified) ArgoCD prod has no broadcast app across all 4 tenants. Helm chart exists but not deployed. Gen 1 peeq-mux-livestream used deprecated Mux Spaces. No Gen 2 broadcast service exists. Frontend broadcast code is dead. 0, 3
H2 Dwolla integration is inactive (wallet doesn’t use it) L2 (Verified) peeq-dwolla not in ArgoCD prod. Gen 2 wallet has zero Dwolla references. peeq-dwolla is Gen 1 (Java 11/SB 2.6.8), last commit Jan 2023. All active payments use Stripe. Frontend DwollaService is dead code. 0, 5
H3 Gen 1 peeq-* services are fully replaced by Gen 2 L1 (Validated across 7 domains + infra) All application domains validated (identity, content, payment, events, communication). Infrastructure: Gen 1 peeq-logging (Node.js) and peeq-shared-secret (Java 11/SB 2.4.3) still active but superseded by Cloud Logging and AVP respectively. ArgoCD deploys only Gen 2 app services. 2-3, 6-8
H4 Frontend unification is architecturally feasible without rewriting business logic L1 (Validated) Both repos are Angular 18.2. Same GraphQL gateways, same auth (Keycloak 26.2), same chat (Stream). Business logic in services is portable. Blocker: CSS framework (Tailwind vs Bootstrap) requires restyling, not logic rewrite. 1
H5 >50% of repos can be archived L1 (Validated) 63 repos last touched before 2025. ArgoCD confirms ~35 app services in prod. Initial estimate: ~110 repos archivable. 0
H6 All inter-service communication uses documented APIs (no shared DB backdoors) L1 (Validated) Across 7 analyzed domains (identity, content, payment, events, communication): all inter-service communication uses GraphQL, REST, or RabbitMQ. Email/SMS/notifications share one PostgreSQL instance (peeq-notification-service-db) — documented shared DB, not a backdoor. No undocumented cross-service DB connections found. 2-7
H7 Gen 2 services have >60% test coverage and consistent API patterns L0 (Falsified for coverage; Validated for patterns) Test coverage is very low across ALL analyzed services (2-3 test files per service, well below 60%). However, API patterns are highly consistent: all use Spring GraphQL, core-lib MessageSender/Handler, SecurityUtil, Keycloak OAuth2. Pattern consistency is L1; coverage fails the >60% threshold. 2-7
H8 Production data volumes are within single-database capacity per domain L0 (Partial) Cloud SQL tier db-custom-2-6656 (2 vCPU, 6.5 GB RAM), 750 max connections, 35 databases per tenant. Data models synthesis: ~280 Flyway migrations across services, proxy estimates suggest moderate volume. Inventory (36 migrations) and Class-Catalog (32) are most complex. Still need actual row counts/table sizes from prod DB. 8-9
H9 No regulatory/compliance constraints block migration approach L0 (updated) Stripe handles all card data (Checkout + Elements). Platform likely SAQ-A scope. No stored payment data found in service code. Need Stripe dashboard to confirm actual PCI scope. PII found in checkout_purchase_recipients (name, email, phone, LinkedIn). 4 (pending 5)
H10 Gen 2 APIs are backward-compatible enough for strangler fig migration L0 (updated) Frontend calls 24+ GraphQL gateways. All use inline gql queries (no .graphql files). ~17% of API calls target non-existent prod services (dead code). Backend schema changes would break both frontends. Need backend-side schema stability analysis. 1 (pending 2)
H11 Multi-brand architecture is purely frontend (theming/CSS), no backend branching L2 (Verified) Fully validated across ALL 7 domains + infrastructure. Infrastructure confirms: same Docker images, same Helm charts deployed to all tenants. All differentiation via values-globals.yaml (domain, Keycloak realm, API keys). No brand-specific code paths anywhere. 4 production tenants use identical service binaries. 2-8
H12 RabbitMQ message contracts between services are discoverable from code L2 (Verified) Cross-cutting synthesis compiled complete inventory: ~75 message types across 7 domains. All follow core-lib MessageSender/MessageHandler pattern. Full contract map documented in integration-patterns.md. Every producer/consumer pair traceable from code. 2-9
H13 Gen 2 shared libraries (core-lib, messages) are stable foundation for Gen 3 L1 (Validated) core-lib versions 0.0.67-0.0.69 used by all 18+ analyzed Gen 2 services. Communication domain confirms: email (0.0.68), sms (0.0.67), notifications (0.0.69), chat (0.0.67), message-board (0.0.67), sse (0.0.67). Messages lib versions 0.0.48-0.0.73 — wider range but API surface stable. Pattern confirmed across all domains. 2-7
H14 A Gen 3 rewrite is justified over upgrading Gen 2 in place L1 (Falsified) Evidence across 10 sessions supports incremental upgrade: Java 21/SB 3.5.4 is current, patterns are consistent (H13 L1), boundaries are clean (H6 L1), multi-brand is config-only (H11 L2). Debt is in infrastructure/BPM/testing — not application architecture. Full rewrite would duplicate ~280 migrations, 75+ message contracts, 11 API integrations without benefit. Recommendation: upgrade in place with targeted consolidation (35→18 services). 11

Last updated: 2026-01-30 — Session 12 Review by: Updated each session Staleness risk: Low — continuously maintained