Infrastructure — Current State to Mid-Term Re-Architecture¶
Pillar VII Research Brief — Shimmy Strategic Document Suite¶
Scope: This brief maps Shimmy's current infrastructure (public site, internal L4+ site, notification system, microservices, AWS footprint) to a mid-term re-architecture horizon, with Shimmy Shield treated as a major standalone section given it's a genuinely distinct ML pipeline. It is written to be extended — each major section is scoped so it can later become its own dedicated technical document (an ADR set, a service catalogue entry, a runbook) without restructuring this brief.
Part 0 — Current-State Baseline¶
0.1 As documented today¶
| Layer | Current implementation |
|---|---|
| Frontend | Flutter/Dart mobile client + Vue 3.5+, TypeScript 5.8+, Vite 7.1+, Tailwind 3.4+, Vue Router 4.5+, Axios for public web and internal L4+ site |
| Core API | Laravel 11, PHP 8.3+, Sanctum bearer-token auth + API key middleware, versioned api/v1 routes |
| Web/internal services | Node.js 20+, Express, worker services for notifications and internal automations |
| Compute | AWS Lambda (API handlers), EC2/Fargate (worker services) |
| Data | Aurora MySQL (relational), ElastiCache Redis (queues/cache), S3 (assets) |
| Messaging | SES email delivery, multi-channel notification service (email/SMS/push/in-app), scheduled delivery and retry backoff via BullMQ |
| Observability | CloudWatch |
| CI/CD | GitHub Actions, Docker, AWS Amplify (hosting/deployment) |
| Services | User Management (L4+), Content Management (public API), Payment Processing (L5 only), Analytics (L3+), Notification (L4+), Recommendations (in development), Explore (public API) |
0.3 Runtime topology and delivery flow¶
Shimmy currently runs as a hybrid platform:
- Mobile/web product surface: Flutter/Dart mobile app and Vue/TypeScript web experiences consume the versioned Laravel API layer.
- Internal operations surface: L4/L5 internal dashboard controls notifications, user access, and system administration.
- Notification execution: templates, scheduling, and channel routing are handled through queue-backed worker services with delivery audit logging in Aurora.
- Content and media path: user content is written through API services and media assets are stored in S3.
0.2 Honest read of the current architecture's shape¶
This is a Lambda-and-managed-services-first architecture — sensible and appropriately lean for current stage, but it has an implicit ceiling worth naming now rather than discovering under load:
- Service boundaries currently look like they're defined by access-level (L3/L4/L5) as much as by domain responsibility. That's a reasonable v1 shortcut but conflates authorisation policy with service architecture — worth deliberately separating before the service count grows further (Part 1).
- BullMQ/Redis as the sole job-queue mechanism is fine at current volume but becomes a scaling and observability constraint once cross-service event flows (not just background jobs) start to matter — this is precisely the transition Part 2 addresses.
- Aurora MySQL as the single relational store across Notification, User Management, Analytics, and (per the Shimmy Shield README) a separate SQLite store for moderation audit logs, is an early signal of data-layer fragmentation that should be resolved deliberately rather than left to accumulate (Part 2.3, Part 3.5).
Part 1 — Near-Term Foundations (Brief, as Groundwork for the Mid-Term Work)¶
Kept intentionally short since the mid-term horizon is the priority, but these are the prerequisites the 2–5yr work depends on:
- Resolve the currently-flagged auth-bypass work on fix/auth-bypass-and-shimmy-image and restore a green, trusted test suite — the re-architecture work in Part 2 (service boundary changes, multi-region auth) is materially riskier to execute against an unverified auth layer, so this is a hard prerequisite, not parallel work.
- Establish an Architecture Decision Record (ADR) practice now, before the mid-term re-architecture generates the volume of consequential decisions Part 4.3 assumes exists as a trail.
Part 2 — Mid-Term Re-Architecture (2–5 Years)¶
2.1 Service boundary maturity: from access-level to domain-driven¶
Recommend re-deriving service boundaries around genuine domain ownership (fundraising/payments, identity, content/moderation, notification, analytics, recommendations) with access control (L3/L4/L5/Admin) implemented as a cross-cutting policy layer (a shared auth/claims service every microservice calls into) rather than a boundary-defining property of the services themselves. This directly supports the Operations pillar's pod model — a pod can own a genuine domain service end-to-end without also having to own bespoke access-control logic duplicated across services.
| Current framing | Recommended mid-term framing |
|---|---|
| "User Management Service (L4+ Access)" | User/Identity Service, with L4+ enforced via shared policy layer |
| "Payment Processing Service (L5 Only)" | Payments Service, with L5 enforced via shared policy layer, plus dedicated PCI-scope isolation (see 2.5) |
| "Analytics Service (L3+ Access)" | Analytics Service, access-scoped via policy layer, decoupled from the ingestion pipeline (2.4) |
2.2 API Gateway and event-driven evolution¶
Current Lambda + API Gateway pattern works well for request/response API handlers. As service count and cross-service interaction grows, recommend introducing an event backbone (EventBridge, or a Kafka-class stream if volume justifies it by year 3–4) alongside — not instead of — the existing request/response layer:
- Request/response (API Gateway → Lambda) stays for synchronous, user-facing calls.
- An event bus carries domain events (fundraiser created, donation completed, moderation verdict issued, user verified) that multiple services need to react to independently — this is what lets, for example, the Notification service, Analytics service, and a future Recommendations engine all react to a donation-completed event without the Payments service needing to know about any of them, directly supporting decoupled pod ownership.
- BullMQ/Redis remains appropriate for intra-service job queues (retry logic, scheduled sends) but should not become the de facto cross-service integration mechanism as more services are added — that pattern degrades badly (implicit coupling via shared queue naming conventions) once more than a handful of services participate.
2.3 Data layer evolution¶
| Current | Mid-term recommendation | Rationale |
|---|---|---|
| Single Aurora MySQL cluster shared across services | Aurora per-domain (or per-domain schema with strict access boundaries as an interim step) | Prevents cross-service coupling via shared tables, a common source of "can't deploy independently" pain as pods multiply |
| Aurora MySQL 8.0 | Evaluate Aurora Serverless v2 for variable-load services (notification bursts, analytics) vs. provisioned for steady-load services (payments) | Cost efficiency matched to actual load shape, rather than one provisioning model for everything |
| ElastiCache Redis (queues + caching, same cluster) | Split queue Redis from cache Redis once either workload's scaling needs diverge (they usually do — cache wants high hit-rate/eviction tuning, queues want durability guarantees) | Avoids one workload's scaling event degrading the other |
| SQLite audit log (Shimmy Shield) | Migrate to Aurora or a dedicated append-only/time-series store before multi-region moderation load (Part 3.5) | SQLite's single-writer model is a hard ceiling well before Shield needs to operate at the volume implied by global rollout |
2.4 Multi-region architecture¶
Directly informed by the Global Markets pillar's Tier 1–3 sequencing:
- Read path: CloudFront + regional edge caching for the public site is likely sufficient through Tier 1 (UK/Ireland/Canada/ANZ) without a full active-active database rebuild — most read-heavy public content doesn't need multi-region write capability yet.
- Write path: Aurora Global Database (or equivalent) becomes relevant once Tier 2/3 markets with data-residency requirements (EU DSA-scope data, India's data-localisation rules per the Global Markets brief) are entered — this should be scoped as a market-entry prerequisite for those specific markets, echoing the same "prerequisite not afterthought" framing used for payment-rail localisation in the Global Markets brief, not a general infrastructure upgrade done speculatively ahead of need.
- Data residency: recommend a per-market data-residency matrix (which user data must stay in-region, which can be centrally processed) be maintained as a living document jointly owned by Infrastructure and Legal/Compliance, reviewed at each new market-tier entry — this is exactly the kind of cross-functional artefact that should exist before, not after, a Tier 3 market commitment is made.
2.5 Security & compliance hardening¶
- Payments isolation: given L5-only payment processing already exists as a concept, recommend formalising this as genuine PCI-DSS scope isolation (separate VPC/network boundary, minimal blast radius) as part of the service boundary rework in 2.1 — worth doing as part of the re-architecture rather than as a separate later project, since retrofitting network isolation onto an already-live payments service is materially more disruptive.
- Audit logging consistency: the notification system's Aurora-based audit logging is the right pattern; Shimmy Shield's SQLite audit logging is not yet at that standard (2.3) — recommend a single audit-logging standard (schema, retention, access-control) applied consistently across every service that produces compliance-relevant logs, directly supporting the rationale-capture discipline flagged in both the moderation brief and the Operations brief.
- GDPR-class data retention: already implemented for the notification system per the current README — recommend this become a shared, reusable data-retention service/library other services (User Management, Shimmy Shield audit logs) consume, rather than each service reimplementing retention logic independently.
2.6 Observability maturity¶
CloudWatch is an adequate starting point but becomes a limiting factor once cross-service tracing matters (a single user-facing request now touching Identity, Content, Notification, and Shield services). Recommend adopting OpenTelemetry instrumentation across services in this horizon specifically so traces are portable regardless of downstream backend choice (CloudWatch, or a dedicated APM tool if cost/features justify a switch later) — instrumenting with a vendor-neutral standard now avoids a second migration later.
2.7 CI/CD maturity¶
Current GitHub Actions + Docker + Amplify stack is appropriate for the current service count. As service count grows under the domain-boundary rework (2.1), recommend:
- Per-service pipelines with independent deploy cadences (a direct technical enabler of the Operations pillar's pod-level autonomy — a pod shouldn't need another pod's release to ship).
- Canary or blue-green deployment for anything touching Payments or Identity specifically, given the blast-radius asymmetry of those services versus, say, the public content site.
Part 3 — Shimmy Shield: Path to V2+¶
3.1 Current architecture, read against the moderation brief's tiering model¶
Correction from an earlier draft of this document: Shimmy Shield V1 is not a flat, always-on ensemble — the full V1 Implementation detail is documented in the Shimmy Shield brief, and it already implements genuine tiered routing: a Layer 0 metadata Risk Vector, a Layer 1 RoBERTa/Toxic-BERT fast pass, and Layer 2's Gemma 3 escalation invoked conditionally on only the Grey Zone (score 0.20–0.80, roughly 10–15% of posts) rather than on every request. The table below reflects that reality, not the flat-ensemble assumption an earlier pass of this document made.
| Moderation brief tier | Shield V1's actual equivalent | Genuine V2+ gap |
|---|---|---|
| Tier 0 (cheap, high-recall filter) | Layer 0 metadata Risk Vector (account age, trust record, destination Shimmy) plus the Two-Tiered Hash Defence (exact-match + similarity) — a real pre-filter, not merely conceptual | Extend Tier 0 to cover image/video content, which is currently text-only (see 3.4 below) |
| Tier 1 (contextual mid-size model) | Layer 1: RoBERTa + Toxic-BERT concurrent fast pass, sub-50ms, with unanimous-clear and unanimous-violation short-circuits that skip Gemma 3 entirely | Category-specific threshold tuning already exists (Production Tweaks, Shimmy Shield brief) — the remaining gap is validating these thresholds against real production data once volume exists, not building the mechanism |
| Tier 2 (escalation reasoning) | Layer 2: Gemma 3, invoked only on Grey Zone content (score 0.20–0.80) with Shimmy-context enrichment pulled from PostgreSQL | Already conditional, already context-enriched — the main open item is the region-conditioned policy layer for multi-market rollout (3.3, below), not making invocation conditional (that's already true) |
The cost-discipline conclusion still holds — tiered routing, not model choice, is the primary lever on blended inference cost — but the credit for having already built it belongs to V1, and V2+'s job is extending the same discipline to multimodal content and multi-region policy variation, not introducing tiering from scratch.
This tiering discipline — Gemma 3 invoked only where the fast lane can't confidently decide — is likely the single largest reason Shield's inference cost scales sub-linearly rather than linearly with content volume, directly consistent with the moderation brief's Horizon 1 conclusion that tiered routing, not model choice, is the primary lever on blended inference cost. At current scale this may be a modest saving; at the volume implied by Tier 1–2 global rollout (Global Markets pillar), it becomes the difference between manageable and unmanageable inference spend.

This is why the tiering discipline compounds rather than becoming unnecessary over time: per-token cost is falling fast, but reasoning-token consumption and always-on agentic workloads are growing — see Market Appendix, Section E.2 for the full nuance.
3.2 Preprocessing pipeline evolution¶
The current 30+ obfuscation patterns and 15+ slang expansions are a reasonable rules-based v1 approach but are inherently a maintenance-debt-accumulating pattern — every new obfuscation technique or slang term requires a manual rule addition, and adversaries adapt faster than manual rule sets can be maintained (directly echoing the moderation brief's adversarial-ML research vector). Recommend V2 evaluate a learned normalisation layer (a small fine-tuned model that handles obfuscation/slang normalisation as a generalisable task rather than a fixed rule list) as a medium-term replacement, with the existing rule-based system kept as a fast-path fallback rather than discarded outright.
3.3 Multi-region policy variation¶
Per the Global Markets pillar's localisation work, Shimmy Shield's 5-category severity classification will need region-specific calibration, not a single global model — what counts as Category 3 (harassment/profanity) versus acceptable register genuinely varies by market and regulatory regime. Recommend:
- Keep the core ensemble architecture global (the underlying models don't need per-region retraining).
- Introduce a region-conditioned policy layer on top of the ensemble output — the same underlying confidence scores and category classification feed into region-specific thresholding/action rules, rather than retraining separate models per region. This is materially cheaper to maintain than N regional model variants and matches the "community-local norm embeddings" pattern from the moderation brief, applied at country/region granularity.
3.4 Real-time and multimodal extension¶
Current Shield V1 is text-focused. Extending to the moderation brief's Horizon 1 multimodal scope (image/video moderation) should be planned as an additive service, not a rework of the existing text ensemble:
- A separate VLM-based image/video moderation path, following the same Tier 0/1/2 structure independently, sharing only the confidence-thresholding and audit-logging infrastructure with the text pipeline.
- Adaptive frame sampling for video (per the moderation brief) rather than dense per-frame analysis, for cost reasons that scale even more steeply for video than for the text ensemble.
3.5 Data infrastructure: the SQLite ceiling¶
Flagging this plainly as a near-term risk, not a distant one: SQLite's single-writer model is not compatible with the audit-log volume implied by global, multi-region rollout, let alone the multi-region policy layer in 3.3, which will want to query audit history for calibration purposes. Recommend migrating Shield's audit logging to Aurora (matching the notification system's existing, proven pattern per 2.3/2.5) before — not during — the first Tier 2 market rollout, since a mid-rollout database migration under live load is a materially riskier and more disruptive change than doing it as a deliberate pre-rollout step.
3.6 Rate limiting and reliability at scale¶
Current 100 requests/60 seconds per-user rate limiting is a sensible per-user control but doesn't address aggregate system-level load once request volume scales with global user growth. Recommend adding a system-level adaptive rate-limiting/backpressure layer (shedding load toward the Tier 0 fast-path preferentially over dropping requests outright) as part of the V2 tiering work in 3.1 — this is a natural extension of the same architecture change, not a separate project.
3.7 Confidence thresholding as the connective tissue¶
Shield V1's thresholding is more granular than a single global cutoff — the V1 Implementation section documents category-specific auto-hide/auto-approve bands (severe toxicity at ≥0.75/<0.30, spam at ≥0.85/<0.40, profanity at ≥0.90/<0.50), which is already, functionally, the moderation brief's "calibrated abstention" concept applied per-category rather than globally. Recommend extending this same category-specific thresholding matrix to serve as the routing trigger for the resonance/trust-metric input feeding the Product pillar's provenance-badge display (Product brief, Part 5) — this is a case where a mechanism already built for moderation is directly reusable as shared infrastructure across pillars, rather than re-implemented per consumer.
Part 4 — Cross-Cutting Infrastructure Decisions¶
4.1 Build vs. buy, infrastructure-specific¶
Consistent with the Operations pillar's build-vs-buy framework, applied here:
| Category | Default | Rationale |
|---|---|---|
| Base ensemble models (RoBERTa, Toxic-BERT) | Buy/use open pretrained weights, fine-tune in-house | Not a differentiator; the tiering/routing architecture and calibration data are |
| Gemma3:12b (or successor) hosting | Buy (API-based) at current scale; revisit self-hosting only above a defined volume threshold, consistent with the moderation brief's own conclusion | Avoid premature self-hosting investment |
| Event backbone (2.2) | Buy (managed EventBridge/equivalent) initially; revisit self-managed streaming only if volume/latency needs exceed managed-service limits | Consistent with the "buy the commodity layer" pattern used throughout the other pillars |
| Observability backend | Start with CloudWatch + OpenTelemetry instrumentation; revisit dedicated APM only once cross-service tracing needs exceed CloudWatch's practical limits | Vendor-neutral instrumentation now avoids lock-in regardless of the later choice |
4.2 Cost modelling against Global Markets sequencing¶
Recommend infrastructure cost projections be built market-by-market, aligned to the Global Markets pillar's tiering, rather than as a single global infrastructure budget line — multi-region database costs, data-residency compliance overhead, and Shimmy Shield's regional policy-layer maintenance all scale with which markets are entered, not just with user count, so the two pillars' planning cycles should be reviewed jointly at each new market-tier decision.
4.3 Documentation structure (space for further documentation)¶
Recommend the following living documentation set sit underneath this brief, each maintained independently and referenced from here rather than duplicated:
- ADR log — one lightweight record per consequential architecture decision (service boundary changes, data store choices, the Tier 0/1/2 routing decisions in Part 3), timestamped and never deleted, only superseded.
- Service catalogue — one page per service (owner pod, dependencies, data stores, SLOs) kept current as services are added or re-scoped under 2.1.
- Runbooks — incident-response procedures per service class, extending the Operations pillar's minimum-viable-discipline recommendation.
- Regional configuration matrix — the data-residency and Shield policy-layer configuration per market, referenced in 2.4 and 3.3, updated at every market-tier entry.
This structure is designed so that as Shimmy scales, this brief remains the stable map while the underlying documents absorb the churn — matching the same "map vs. deep-dive" relationship the master strategy suite architecture established for the six business pillars.
Cross-link Index¶
- Related decisions: Pillar II, Pillar III, Shimmy Shield
- Related metrics: Financials, Roadmap & Milestones
- Related risks: Risk Register