Effect Rewrite - #73
Merged
Merged
Conversation
Rewrite team-shared-core and team-shared-data as Effect services with Context.Tag, Layer composition, Cache.make with 30s TTL, wide event logging, OTel spans, and typed errors via S.TaggedError. These form the base layer that all other team services depend on.
Leaf services with no cross-domain dependencies. Each follows the standard 4-file pattern (service, errors, types, metrics) with Effect caching, wide event logging, and OTel spans.
Split comparison-dto into aggregation-service, trends-service, and a pure computation module. The computation module holds aggregatePlayerStats and calculateTrends as side-effect-free functions shared across domains.
Scouting covers opponent match data and Elo-like strength ratings. Intelligence covers hero ban analysis and map strategy, consuming scouting and team services via Effect Context dependencies.
Covers scrim metadata, overview analysis, opponent data, ability timing, fight timelines, and per-player stats/winrates. Overview and opponent services consume TeamSharedDataService and ScrimAbilityTimingService via Effect Context. Includes ult-helpers for shared pure functions.
Covers player stats, intelligence analysis, scouting profiles, scouting analytics, and performance targets. Intelligence service consumes team, scouting, and scrim services via Effect Context dependencies.
Covers heatmaps, killfeed analysis with calibration, replay visualization, tempo (Gaussian KDE), rotation death detection, and map group CRUD. Uses nested sub-domains for heatmap, killfeed, and replay.
13 domain services covering stats, trends, fight analysis, role stats, hero pool, hero swaps, map mode, quick wins, ult impact/stats, ban impact, ability impact, team comparison, and matchup/enemy hero analysis. Each consumes TeamSharedDataService via Effect Context.
Single entry point that merges all 41 service layers. Effect's layer memoization ensures EffectObservabilityLive initializes once regardless of how many services depend on it.
Single ManagedRuntime created from DataLayerLive. All consumer files will use AppRuntime.runPromise to execute Effect programs at the RSC/API boundary.
Switch 89 files from @/data/user-dto to UserService via AppRuntime. Each await getUser(email) becomes AppRuntime.runPromise(UserService.pipe(Effect.flatMap(...))).
Switch 39 files from scrim-dto, scrim-overview-dto, and scrim-ability-timing-dto to ScrimService, ScrimOverviewService, and ScrimAbilityTimingService via AppRuntime. Update scrim barrel exports to re-export all consumer-facing types and utilities.
Switch 14 files from comparison-dto to ComparisonAggregationService via AppRuntime. Pure functions (aggregatePlayerStats, calculateTrends) redirected to @/data/comparison/computation.
…fect Switch 6 files from scouting-dto and opponent-strength-dto to ScoutingService and OpponentStrengthService via AppRuntime.
Switch remaining DTO imports in AI tool definitions to use ScrimOverviewService, ScrimAbilityTimingService, and ComparisonAggregationService via AppRuntime.
Add "server-only" to all domain barrel index.ts files so only server
components can import services. Extract all client-needed types from
service files into types.ts files (team: 40+ types, scrim: Winrate +
PlayerUltSummary). Client components now import types from
@/data/{domain}/types instead of the barrel. Service files re-import
types from types.ts to maintain backward compatibility for server
consumers importing from the barrel.
Migrate team-analytics-dto (3 functions: getHeroPickrateMatrix, getPlayerMapPerformanceMatrix, getHeroPickrateRawData) and team-prediction-dto (1 function: getSimulatorContext) to Effect services. Prediction service composes 6 team services via Effect.all for parallel execution. Both added to DataLayerLive.
Move 50+ types from team, scrim, and map service files to their respective types.ts for client-safe imports. Service files re-import from types.ts. Add tempo and killfeed pure functions to client-safe type/helper files. Add server-only to runtime.ts.
Switch 73 client components from old DTO type imports to client-safe
@/data/{domain}/types paths. No service imports in client components.
Pure functions (killfeed helpers, tempo utils) imported from
client-safe helper files.
Switch ai/tools.ts to use 9 Effect services via AppRuntime. Update team-normalization.ts to use TeamSharedDataService. Redirect type imports in hero-pool-utils, insights, replay/build-player-timeline, and prediction-engine to new type paths. Leave calculate-stats, analytics, and mvp-score on old DTOs (client import chain).
…Effect Switch 22 files including the team stats page (14 service imports composed via Effect.all), tournament pages, scouting pages, player pages, map pages, and all remaining API routes to use Effect services via AppRuntime. Fix tournament service types for query payloads.
Break the static import chain from scrim-creator.tsx (client) through parser.ts to calculate-stats.ts by using dynamic import(). This allows calculate-stats.ts, analytics.ts, and mvp-score.ts to safely import AppRuntime and use Effect services. Migrate remaining component and lib type imports to new paths.
Extract client-safe parsing functions (parseData, parseDataFromTXT, parseDataFromXLSX, normalizeTeamData) to parser-client.ts. Client components import from parser-client.ts which has no server deps. parser.ts keeps server-only functions (createNewScrim, calculateStats) and gets "server-only" guard. runtime.ts restored with "server-only".
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Member
Author
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
![Screenshot of /[team]/compare](https://images.weserv.nl?url=https://sjc.microlink.io/MLS5LQUYVL_DBR6RUOBLbI7cPseU9TinpUI9G4Wk3njNEqMOuCOxogSu5lGtsfLsEf4sg4dfvHDfj12_ETR80Q.png&w=600)
![Screenshot of /[team]/map-groups](https://images.weserv.nl?url=https://sjc.microlink.io/LAiHd6bvhQtcsCSBVj6YSO5GNqArvZmRllpYv14AR_IRm32HS1MT1xvnu6LhrlWc5W0rS6u3xvOZtg_6pwiYTg.png&w=600)
![Screenshot of /[team]/scrim/[scrimId]/edit](https://images.weserv.nl?url=https://sjc.microlink.io/Nv_5NUzgXeQoWGkalFN6wB0JeQXNb44SVQezBmt1WgiQ1VH-ArmifYlkJ6vsZlztkc_y5AgHdyVM1D6YKUqNQA.png&w=600)
![Screenshot of /[team]/scrim/[scrimId]/map/[mapId]](https://images.weserv.nl?url=https://sjc.microlink.io/3AqeFclE9yFTq5ScXaeWo_2JAOE_CnPg3WdlhiuNpgrTfmccUWkr1EwgKBWA8YsJE767BIYPjzeGJ-3BXZwvAw.png&w=600)
![Screenshot of /[team]/scrim/[scrimId]/map/[mapId]/player/[playerId]](https://images.weserv.nl?url=https://sjc.microlink.io/uV78AXDweCZAo2NbDv_nDFXBQYvmw0VR735ENDaYHRtOKMlLLD6FtGhqwdPpyAZnVtdfAld0fu_aKYeHNdmv8A.png&w=600)
![Screenshot of /[team]/scrim/[scrimId]](https://images.weserv.nl?url=https://sjc.microlink.io/8ucb1O5Vn4CVqLNar7ElEGTqtJY6vfsdIBH3K1S2ILmyJV6mcgNU2kI0K2o5hJJ0xdBITECvJQeDoulm_Ok-gA.png&w=600)
No description provided.