mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-19 13:36:48 +00:00
ae3ba18b9e
Fold the 1612-line services/atlasService.ts into the DI-native AtlasService: the stats aggregation, visited countries/regions with the #1490 tombstone and cascade logic, and the bucket-list CRUD become methods over the injected DatabaseService. The ~750-line pure-geo half — the bundled admin0/admin1 boundary stores with their #1576 streaming builders, the point-in-polygon indexes, Nominatim geocoding with its shared throttle, and every module-scoped cache including the import-time unref'd cleanup interval — moves verbatim to the plain module atlas-geo.ts so the caches stay process-global across the container instance, the bridge instance and test helpers (assetPath re-anchored one directory deeper, the only non-verbatim line). The 10-tool mcp/tools/atlas.ts registrar plus all four atlas resources in mcp/resources.ts move onto the decorator registry as atlas.mcp.ts — the when: atlas-addon gate is parity here (legacy tools and resources both gated; the REST controller deliberately does not). resources.test.ts retires with its last two cases, which move to tools-atlas-expanded.test.ts. The plugin RPC host swaps its 9 atlas imports for the injected AtlasService (23rd constructor dep); a minimal 2-export atlas.bridge.ts serves the one legacy consumer, authService.getTravelStats, and dies when authService migrates. Adopts atlas.dto.ts over the existing shared schemas and clears all three AtlasController entries from body-contract-allow-list.ts: the hand-rolled 'name and country_code are required' 400 becomes the ZodValidationPipe envelope (todo/places trade) while the whitespace-only bucket name keeps its legacy 'Name is required' trim guard. Fixes the verified defects the relocation had faithfully carried, each with a regression test (ATLAS-SVC-031..036 plus two MCP casing cases): the four multi-statement mark/unmark writes now run in db.transaction() (the region cascade nests as a savepoint), the trip-less countryPlaces early return honours manually_marked, the '|| null' bindings that dropped lat/lng 0 and empty-string notes on bucket update become '?? null', the mutating bucket SQL is user-scoped, and the MCP region/country-places tools uppercase their codes to match REST. Quirks deliberately preserved: the detached GET-path place_regions backfill writes, getStats' two divergent return shapes, the import-time cache-cleanup interval, getCountryFromAddress's unvalidated bare 2-letter codes, and the whitespace-only-name silent no-op on bucket update. Tests move with their case IDs: atlasService.test.ts becomes unit/nest/atlas.service.test.ts (pure-geo imports from atlas-geo, DB calls through the constructed service, plus bridge-delegation cases), the atlas e2e converts to the DI-native pattern (real SQL against the full temp-db schema), and the plugin-host path mock becomes a constructor stub.
82 lines
4.3 KiB
TypeScript
82 lines
4.3 KiB
TypeScript
import { DatabaseService } from '../../src/nest/database/database.service';
|
|
import { PluginRuntimeService } from '../../src/nest/plugins/plugin-runtime.service';
|
|
import type { PluginRegistryService } from '../../src/nest/plugins/registry/registry.service';
|
|
import { PluginHostDepsFactory } from '../../src/nest/plugins/host/plugin-host-deps.factory';
|
|
import { PluginOAuthService } from '../../src/nest/plugins/plugin-oauth.service';
|
|
import { BudgetService } from '../../src/nest/budget/budget.service';
|
|
import { ExchangeRatesService } from '../../src/nest/budget/exchange-rates.service';
|
|
import { ReservationsService } from '../../src/nest/reservations/reservations.service';
|
|
import { TagsService } from '../../src/nest/tags/tags.service';
|
|
import { CategoriesService } from '../../src/nest/categories/categories.service';
|
|
import { TodoService } from '../../src/nest/todo/todo.service';
|
|
import { PackingService } from '../../src/nest/packing/packing.service';
|
|
import { DayNotesService } from '../../src/nest/days/day-notes.service';
|
|
import { DaysService } from '../../src/nest/days/days.service';
|
|
import { AssignmentsService } from '../../src/nest/assignments/assignments.service';
|
|
import { LlmConfigResolver } from '../../src/nest/llm-parse/llm-config.resolver';
|
|
import { SettingsService } from '../../src/nest/settings/settings.service';
|
|
import { FilesService } from '../../src/nest/files/files.service';
|
|
import { CollabService } from '../../src/nest/collab/collab.service';
|
|
import { VacayService } from '../../src/nest/vacay/vacay.service';
|
|
import { TripsService } from '../../src/nest/trips/trips.service';
|
|
import { PlacesService } from '../../src/nest/places/places.service';
|
|
import { CollectionsService } from '../../src/nest/collections/collections.service';
|
|
import { AtlasService } from '../../src/nest/atlas/atlas.service';
|
|
import { MapsService } from '../../src/nest/maps/maps.service';
|
|
import { PermissionsService } from '../../src/nest/permissions/permissions.service';
|
|
import { AuditService } from '../../src/nest/audit/audit.service';
|
|
import { AddonsService } from '../../src/nest/addons/addons.service';
|
|
import { RealtimeService } from '../../src/nest/realtime/realtime.service';
|
|
|
|
/**
|
|
* Hand-wired counterpart of the PluginsModule DI graph for no-Nest tests
|
|
* (same pattern as mcp-test-controllers.ts): real domain services over the
|
|
* test DB, so runtime tests exercise the same wiring production gets from
|
|
* the container.
|
|
*/
|
|
export function createHostDepsFactory(dbs: DatabaseService): PluginHostDepsFactory {
|
|
const permissions = new PermissionsService(dbs);
|
|
const exchangeRates = new ExchangeRatesService();
|
|
const realtime = new RealtimeService();
|
|
const budget = new BudgetService(dbs, permissions, exchangeRates, realtime);
|
|
const addons = new AddonsService(dbs);
|
|
const todos = new TodoService(dbs, permissions, realtime);
|
|
const packing = new PackingService(dbs, permissions, realtime);
|
|
const files = new FilesService(dbs, permissions, realtime);
|
|
const reservations = new ReservationsService(dbs, permissions, budget, realtime);
|
|
const collab = new CollabService(dbs, permissions, realtime);
|
|
const vacay = new VacayService(dbs, realtime);
|
|
const days = new DaysService(dbs, permissions, realtime);
|
|
const places = new PlacesService(dbs, permissions, realtime, new MapsService(dbs));
|
|
return new PluginHostDepsFactory(
|
|
budget,
|
|
reservations,
|
|
new TagsService(dbs),
|
|
new CategoriesService(dbs),
|
|
todos,
|
|
packing,
|
|
new PluginOAuthService(dbs),
|
|
new DayNotesService(dbs, permissions, realtime),
|
|
new AssignmentsService(dbs, permissions, realtime),
|
|
new LlmConfigResolver(new SettingsService(dbs), dbs, addons),
|
|
dbs,
|
|
files,
|
|
collab,
|
|
vacay,
|
|
days,
|
|
permissions,
|
|
exchangeRates,
|
|
addons,
|
|
realtime,
|
|
new TripsService(dbs, todos, packing, files, reservations, days, permissions, budget, collab, vacay, realtime, places),
|
|
places,
|
|
new CollectionsService(dbs, permissions, realtime),
|
|
new AtlasService(dbs),
|
|
);
|
|
}
|
|
|
|
/** A PluginRuntimeService constructed the way Nest would: with a real host-deps factory. */
|
|
export function createPluginRuntime(dbs: DatabaseService, registry?: PluginRegistryService): PluginRuntimeService {
|
|
return new PluginRuntimeService(dbs, new AuditService(dbs), new AddonsService(dbs), registry, createHostDepsFactory(dbs));
|
|
}
|