diff --git a/api/.gitkeep b/api/.gitkeep deleted file mode 100644 index 8b1378917..000000000 --- a/api/.gitkeep +++ /dev/null @@ -1 +0,0 @@ - diff --git a/api/API_RUNTIME_BOUNDARY.md b/api/API_RUNTIME_BOUNDARY.md new file mode 100644 index 000000000..ba4c12c6b --- /dev/null +++ b/api/API_RUNTIME_BOUNDARY.md @@ -0,0 +1,16 @@ +# API Runtime Boundary + +`api/` contains server/API application runtime implementation for the browser-visible Local API, seeded product data, provider stubs, storage adapters, database adapters, and support services used by repository validation. + +It is intentionally not `dev/tests/dev-runtime`: + +- `api/` serves runtime behavior that browser pages and local API routes can exercise through the API/service contract during development and targeted validation. +- `dev/tests/dev-runtime` contains test files that validate that behavior. +- Moving the implementation into `dev/tests/dev-runtime` would make development pages depend on test-only code and would blur the Browser -> Server API -> Data Source boundary. + +Deployment boundary: + +- DEV validation may execute `api/` through local server commands. +- Browser pages, Theme V2 scripts, toolbox pages, and `src/engine` runtime code must use declared API/service contracts instead of importing `api/` directly. +- If a dev-only adapter is needed by a browser page, expose it through the Local API contract while keeping the implementation under `api/`. +- Developer-only local bootstrap/orchestration remains outside `api/` until the scoped `dev/local-runtime/` migration PR. diff --git a/src/dev-runtime/admin/admin-notes-directory.mjs b/api/admin/admin-notes-directory.mjs similarity index 100% rename from src/dev-runtime/admin/admin-notes-directory.mjs rename to api/admin/admin-notes-directory.mjs diff --git a/src/dev-runtime/admin/admin-notes-menu.mjs b/api/admin/admin-notes-menu.mjs similarity index 100% rename from src/dev-runtime/admin/admin-notes-menu.mjs rename to api/admin/admin-notes-menu.mjs diff --git a/src/dev-runtime/ai/ai-credit-service.mjs b/api/ai/ai-credit-service.mjs similarity index 100% rename from src/dev-runtime/ai/ai-credit-service.mjs rename to api/ai/ai-credit-service.mjs diff --git a/src/dev-runtime/ai/owner-ai-credit-settings-service.mjs b/api/ai/owner-ai-credit-settings-service.mjs similarity index 100% rename from src/dev-runtime/ai/owner-ai-credit-settings-service.mjs rename to api/ai/owner-ai-credit-settings-service.mjs diff --git a/src/dev-runtime/auth/.gitkeep b/api/auth/.gitkeep similarity index 100% rename from src/dev-runtime/auth/.gitkeep rename to api/auth/.gitkeep diff --git a/src/dev-runtime/auth/provider-contract-stubs.mjs b/api/auth/provider-contract-stubs.mjs similarity index 100% rename from src/dev-runtime/auth/provider-contract-stubs.mjs rename to api/auth/provider-contract-stubs.mjs diff --git a/src/dev-runtime/database/postgres-backup-service.mjs b/api/database/postgres-backup-service.mjs similarity index 100% rename from src/dev-runtime/database/postgres-backup-service.mjs rename to api/database/postgres-backup-service.mjs diff --git a/src/dev-runtime/guest-seeds/.gitkeep b/api/guest-seeds/.gitkeep similarity index 100% rename from src/dev-runtime/guest-seeds/.gitkeep rename to api/guest-seeds/.gitkeep diff --git a/src/dev-runtime/guest-seeds/palette-source-mock-db.js b/api/guest-seeds/palette-source-mock-db.js similarity index 100% rename from src/dev-runtime/guest-seeds/palette-source-mock-db.js rename to api/guest-seeds/palette-source-mock-db.js diff --git a/api/guest-seeds/tool-metadata-inventory.js b/api/guest-seeds/tool-metadata-inventory.js new file mode 100644 index 000000000..2a7efcf29 --- /dev/null +++ b/api/guest-seeds/tool-metadata-inventory.js @@ -0,0 +1 @@ +export * from "../../src/shared/toolbox/tool-metadata-inventory.js"; diff --git a/src/dev-runtime/guest-seeds/tool-state-samples.js b/api/guest-seeds/tool-state-samples.js similarity index 100% rename from src/dev-runtime/guest-seeds/tool-state-samples.js rename to api/guest-seeds/tool-state-samples.js diff --git a/src/dev-runtime/legal/legal-document-service.mjs b/api/legal/legal-document-service.mjs similarity index 100% rename from src/dev-runtime/legal/legal-document-service.mjs rename to api/legal/legal-document-service.mjs diff --git a/src/dev-runtime/marketplace/marketplace-category-service.mjs b/api/marketplace/marketplace-category-service.mjs similarity index 100% rename from src/dev-runtime/marketplace/marketplace-category-service.mjs rename to api/marketplace/marketplace-category-service.mjs diff --git a/src/dev-runtime/marketplace/marketplace-entitlement-service.mjs b/api/marketplace/marketplace-entitlement-service.mjs similarity index 100% rename from src/dev-runtime/marketplace/marketplace-entitlement-service.mjs rename to api/marketplace/marketplace-entitlement-service.mjs diff --git a/src/dev-runtime/marketplace/marketplace-revenue-service.mjs b/api/marketplace/marketplace-revenue-service.mjs similarity index 100% rename from src/dev-runtime/marketplace/marketplace-revenue-service.mjs rename to api/marketplace/marketplace-revenue-service.mjs diff --git a/src/dev-runtime/memberships/membership-assignment-service.mjs b/api/memberships/membership-assignment-service.mjs similarity index 100% rename from src/dev-runtime/memberships/membership-assignment-service.mjs rename to api/memberships/membership-assignment-service.mjs diff --git a/src/dev-runtime/memberships/owner-membership-settings-service.mjs b/api/memberships/owner-membership-settings-service.mjs similarity index 100% rename from src/dev-runtime/memberships/owner-membership-settings-service.mjs rename to api/memberships/owner-membership-settings-service.mjs diff --git a/src/dev-runtime/messages/messages-postgres-service.mjs b/api/messages/messages-postgres-service.mjs similarity index 100% rename from src/dev-runtime/messages/messages-postgres-service.mjs rename to api/messages/messages-postgres-service.mjs diff --git a/src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs b/api/persistence/game-journey-completion-metrics-store.mjs similarity index 100% rename from src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs rename to api/persistence/game-journey-completion-metrics-store.mjs diff --git a/src/dev-runtime/persistence/mock-db-store.js b/api/persistence/mock-db-store.js similarity index 100% rename from src/dev-runtime/persistence/mock-db-store.js rename to api/persistence/mock-db-store.js diff --git a/src/dev-runtime/persistence/postgres-connection-client.mjs b/api/persistence/postgres-connection-client.mjs similarity index 100% rename from src/dev-runtime/persistence/postgres-connection-client.mjs rename to api/persistence/postgres-connection-client.mjs diff --git a/src/dev-runtime/persistence/tool-repositories/assets-mock-repository.js b/api/persistence/tool-repositories/assets-mock-repository.js similarity index 100% rename from src/dev-runtime/persistence/tool-repositories/assets-mock-repository.js rename to api/persistence/tool-repositories/assets-mock-repository.js diff --git a/src/dev-runtime/persistence/tool-repositories/game-journey-mock-repository.js b/api/persistence/tool-repositories/game-journey-mock-repository.js similarity index 100% rename from src/dev-runtime/persistence/tool-repositories/game-journey-mock-repository.js rename to api/persistence/tool-repositories/game-journey-mock-repository.js diff --git a/src/dev-runtime/persistence/tool-repositories/game-workspace-mock-repository.js b/api/persistence/tool-repositories/game-workspace-mock-repository.js similarity index 100% rename from src/dev-runtime/persistence/tool-repositories/game-workspace-mock-repository.js rename to api/persistence/tool-repositories/game-workspace-mock-repository.js diff --git a/src/dev-runtime/persistence/tool-repositories/hitboxes-mock-repository.js b/api/persistence/tool-repositories/hitboxes-mock-repository.js similarity index 100% rename from src/dev-runtime/persistence/tool-repositories/hitboxes-mock-repository.js rename to api/persistence/tool-repositories/hitboxes-mock-repository.js diff --git a/src/dev-runtime/persistence/tool-repositories/input-mapping-mock-repository.js b/api/persistence/tool-repositories/input-mapping-mock-repository.js similarity index 100% rename from src/dev-runtime/persistence/tool-repositories/input-mapping-mock-repository.js rename to api/persistence/tool-repositories/input-mapping-mock-repository.js diff --git a/src/dev-runtime/persistence/tool-repositories/objects-mock-repository.js b/api/persistence/tool-repositories/objects-mock-repository.js similarity index 100% rename from src/dev-runtime/persistence/tool-repositories/objects-mock-repository.js rename to api/persistence/tool-repositories/objects-mock-repository.js diff --git a/src/dev-runtime/persistence/tool-repositories/palette-catalog-config.js b/api/persistence/tool-repositories/palette-catalog-config.js similarity index 100% rename from src/dev-runtime/persistence/tool-repositories/palette-catalog-config.js rename to api/persistence/tool-repositories/palette-catalog-config.js diff --git a/src/dev-runtime/persistence/tool-repositories/palette-workspace-repository.js b/api/persistence/tool-repositories/palette-workspace-repository.js similarity index 100% rename from src/dev-runtime/persistence/tool-repositories/palette-workspace-repository.js rename to api/persistence/tool-repositories/palette-workspace-repository.js diff --git a/src/dev-runtime/project-packages/project-package-service.mjs b/api/project-packages/project-package-service.mjs similarity index 100% rename from src/dev-runtime/project-packages/project-package-service.mjs rename to api/project-packages/project-package-service.mjs diff --git a/src/dev-runtime/seed/seed-db-keys.mjs b/api/seed/seed-db-keys.mjs similarity index 100% rename from src/dev-runtime/seed/seed-db-keys.mjs rename to api/seed/seed-db-keys.mjs diff --git a/src/dev-runtime/seed/server-seed-loader.mjs b/api/seed/server-seed-loader.mjs similarity index 100% rename from src/dev-runtime/seed/server-seed-loader.mjs rename to api/seed/server-seed-loader.mjs diff --git a/src/dev-runtime/server/local-api-router.mjs b/api/server/local-api-router.mjs similarity index 99% rename from src/dev-runtime/server/local-api-router.mjs rename to api/server/local-api-router.mjs index ae2b7bf72..cd315eee8 100644 --- a/src/dev-runtime/server/local-api-router.mjs +++ b/api/server/local-api-router.mjs @@ -133,7 +133,7 @@ import { import { getAdminNavigationItems, getOwnerNavigationItems, -} from "../../api/admin-owner-navigation.js"; +} from "../../src/api/admin-owner-navigation.js"; import { createPaletteSourceMockDbRows } from "../guest-seeds/palette-source-mock-db.js"; import { SUPABASE_AUTH_PROVIDER_ID, diff --git a/src/dev-runtime/server/local-api-server.mjs b/api/server/local-api-server.mjs similarity index 98% rename from src/dev-runtime/server/local-api-server.mjs rename to api/server/local-api-server.mjs index 53867d1cd..ddd325ed7 100644 --- a/src/dev-runtime/server/local-api-server.mjs +++ b/api/server/local-api-server.mjs @@ -9,7 +9,7 @@ import { resolveStaticRouteTarget } from "./static-web-root.mjs"; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); -const repoRoot = path.resolve(__dirname, "..", "..", ".."); +const repoRoot = path.resolve(__dirname, "..", ".."); function contentTypeForPath(filePath) { const extension = path.extname(filePath).toLowerCase(); diff --git a/src/dev-runtime/server/mock-api-router.mjs b/api/server/mock-api-router.mjs similarity index 100% rename from src/dev-runtime/server/mock-api-router.mjs rename to api/server/mock-api-router.mjs diff --git a/src/dev-runtime/server/static-web-root.mjs b/api/server/static-web-root.mjs similarity index 100% rename from src/dev-runtime/server/static-web-root.mjs rename to api/server/static-web-root.mjs diff --git a/src/dev-runtime/storage/r2-project-asset-storage.mjs b/api/storage/r2-project-asset-storage.mjs similarity index 100% rename from src/dev-runtime/storage/r2-project-asset-storage.mjs rename to api/storage/r2-project-asset-storage.mjs diff --git a/src/dev-runtime/storage/storage-config.mjs b/api/storage/storage-config.mjs similarity index 100% rename from src/dev-runtime/storage/storage-config.mjs rename to api/storage/storage-config.mjs diff --git a/src/dev-runtime/teams/project-team-service.mjs b/api/teams/project-team-service.mjs similarity index 100% rename from src/dev-runtime/teams/project-team-service.mjs rename to api/teams/project-team-service.mjs diff --git a/src/dev-runtime/testing/.gitkeep b/api/testing/.gitkeep similarity index 100% rename from src/dev-runtime/testing/.gitkeep rename to api/testing/.gitkeep diff --git a/src/dev-runtime/testing/supabase-dev-auth-test-user-cleanup.mjs b/api/testing/supabase-dev-auth-test-user-cleanup.mjs similarity index 100% rename from src/dev-runtime/testing/supabase-dev-auth-test-user-cleanup.mjs rename to api/testing/supabase-dev-auth-test-user-cleanup.mjs diff --git a/src/dev-runtime/testing/supabase-dev-creator-identity-seed-sync.mjs b/api/testing/supabase-dev-creator-identity-seed-sync.mjs similarity index 100% rename from src/dev-runtime/testing/supabase-dev-creator-identity-seed-sync.mjs rename to api/testing/supabase-dev-creator-identity-seed-sync.mjs diff --git a/src/dev-runtime/toolbox-api/alfa-tool-services.mjs b/api/toolbox-api/alfa-tool-services.mjs similarity index 100% rename from src/dev-runtime/toolbox-api/alfa-tool-services.mjs rename to api/toolbox-api/alfa-tool-services.mjs diff --git a/dev/build/ProjectInstructions/PROJECT_INSTRUCTIONS.md b/dev/build/ProjectInstructions/PROJECT_INSTRUCTIONS.md index febd6861c..5f477a565 100644 --- a/dev/build/ProjectInstructions/PROJECT_INSTRUCTIONS.md +++ b/dev/build/ProjectInstructions/PROJECT_INSTRUCTIONS.md @@ -117,7 +117,7 @@ Rules: ## Current Version/Date -- Project Instructions Version: 2026.06.28.008 +- Project Instructions Version: 2026.06.28.009 - Date: 2026-06-28 - Owner: OWNER diff --git a/dev/build/ProjectInstructions/PROJECT_INSTRUCTIONS_VERSION.md b/dev/build/ProjectInstructions/PROJECT_INSTRUCTIONS_VERSION.md index 6ffb05a98..973eb9002 100644 --- a/dev/build/ProjectInstructions/PROJECT_INSTRUCTIONS_VERSION.md +++ b/dev/build/ProjectInstructions/PROJECT_INSTRUCTIONS_VERSION.md @@ -1,6 +1,6 @@ # Project Instructions Version -Current Project Instructions Version: 2026.06.28.008 +Current Project Instructions Version: 2026.06.28.009 Last Updated: 2026-06-28 @@ -16,6 +16,7 @@ Last Updated: 2026-06-28 - Added `www/` migration map for safe browser-served application movement planning. - Added local route-root compatibility toggle documentation for future `www/` activation. - Moved browser-served application files under `www/` and made local static serving prefer `www/` by default. +- Moved server/API application runtime under `api/`; browser API clients remain outside `api/` and developer-only bootstrap remains in `dev/` until the local-runtime migration PR. - Codex must read this version file and the latest repository copy of `PROJECT_INSTRUCTIONS.md` before performing work. - Codex must discard previously remembered Project Instructions and treat the repository copy as authoritative. - Codex must validate canonical report and ZIP paths, branching model, and legacy path avoidance before work proceeds. diff --git a/dev/build/ProjectInstructions/PROJECT_STATE.md b/dev/build/ProjectInstructions/PROJECT_STATE.md index aea9601ef..3b1323747 100644 --- a/dev/build/ProjectInstructions/PROJECT_STATE.md +++ b/dev/build/ProjectInstructions/PROJECT_STATE.md @@ -1,7 +1,7 @@ # Project State ```yaml -project_state_version: "2026.06.28.008" +project_state_version: "2026.06.28.009" last_updated: "2026-06-28" current_main_commit: "40de767476d70cadfd1292c916844c2f31b6f185" repository_status: @@ -10,9 +10,9 @@ repository_status: runtime_database: "Postgres" creator_metadata: "API to Postgres" creator_assets: "API to R2" -project_instructions_version: "2026.06.28.008" -repository_structure_version: "2026.06.28.008" -canonical_layout_version: "2026.06.28.008" +project_instructions_version: "2026.06.28.009" +repository_structure_version: "2026.06.28.009" +canonical_layout_version: "2026.06.28.009" active_teams: - "Owner" - "Alfa" @@ -20,8 +20,8 @@ active_teams: - "Charlie" - "Delta" - "Golf" -latest_owner_pr: "PR_26180_OWNER_008-move-www-application" -latest_structure_pr: "PR_26180_OWNER_008-move-www-application" +latest_owner_pr: "PR_26180_OWNER_009-move-api-application" +latest_structure_pr: "PR_26180_OWNER_009-move-api-application" valid_top_level_folders: - "api/" - "deploy/" @@ -40,6 +40,7 @@ valid_dev_folders: - "dev/tools/" - "dev/workspace/" known_technical_debt: - - "Legacy transition src buckets remain until scoped migration PRs move them into src/web/, src/api-runtime/, or src/runtime/." + - "Browser API client modules remain under src/api/ until the final src layer migration moves them into src/web/ or src/runtime/." + - "src/dev-runtime/admin/ remains as a legacy Admin Notes browser-viewer compatibility path until a scoped browser admin migration retires it." - "repository_directory_standard.md and codex_project_instructions_startup.md are superseded pointers retained for compatibility." ``` diff --git a/dev/build/ProjectInstructions/backlog/BACKLOG_MASTER.md b/dev/build/ProjectInstructions/backlog/BACKLOG_MASTER.md index 6b947089c..0f32f8f6d 100644 --- a/dev/build/ProjectInstructions/backlog/BACKLOG_MASTER.md +++ b/dev/build/ProjectInstructions/backlog/BACKLOG_MASTER.md @@ -39,9 +39,9 @@ The backlog is the authoritative source for determining the next logical PRs. - Team: Owner - Product Area: Repository Architecture Simplification - Status: Active -- Percent Complete: 30% -- Active PR: PR_26180_OWNER_008-move-www-application -- Next Milestone: Move server/API application files into `api/` +- Percent Complete: 40% +- Active PR: PR_26180_OWNER_009-move-api-application +- Next Milestone: Move developer-only local runtime into `dev/local-runtime/` - Source / Reference: `dev/build/ProjectInstructions/repository/repository_layout_architecture_plan.md`; `dev/build/ProjectInstructions/repository/www_migration_map.md` ## Game Journey MVP diff --git a/dev/build/ProjectInstructions/repository/canonical_repository_structure.md b/dev/build/ProjectInstructions/repository/canonical_repository_structure.md index 7ef868a5b..848c9f767 100644 --- a/dev/build/ProjectInstructions/repository/canonical_repository_structure.md +++ b/dev/build/ProjectInstructions/repository/canonical_repository_structure.md @@ -15,7 +15,7 @@ Valid top-level folders: Root product and repo sections: - www/ owns browser-served production website sections, Creator toolbox pages, public game discovery, production Docs & Help, and browser assets. -- api/ is the target Node/API/server application surface for the repository layout simplification workstream. +- api/ is the Node/API/server application surface for server entry points, API routing, API services, database access, storage access, auth, setup, publishing, and admin server logic. - deploy/ contains deployment configuration. - dev/ contains the development workspace. - src/ contains deployable application/runtime/API source. @@ -30,7 +30,9 @@ Final src layer ownership: - src/web/ owns browser-facing deployable application modules used by public pages, account/admin surfaces, and Creator tools. - src/api-runtime/ owns deployable API/runtime service modules that back the shared Browser -> API -> Postgres/R2 contract. - src/runtime/ owns deployable game, tool, engine, and shared runtime capabilities. -- Existing top-level src/advanced/, src/api/, src/dev-runtime/, src/engine/, src/shared/, and src/tools/ directories are legacy transition buckets until explicit migration PRs move them. +- Existing top-level src/advanced/, src/api/, src/engine/, src/shared/, and src/tools/ directories are legacy transition buckets until explicit migration PRs move them. +- Browser API clients remain outside `api/`; browser-served code must use API/service contracts instead of importing top-level `api/` files directly. +- `src/dev-runtime/admin/` remains only as a legacy Admin Notes browser-viewer compatibility path until a scoped browser admin migration retires it. - Do not add new top-level src/ layer names outside src/web/, src/api-runtime/, or src/runtime/ without OWNER approval. - Do not use team names in runtime source filenames. @@ -75,10 +77,10 @@ Shared JavaScript: Legacy transition buckets: - src/advanced/ - src/api/ -- src/dev-runtime/ - src/engine/ - src/shared/ - src/tools/ +- src/dev-runtime/admin/ These legacy transition buckets may remain until explicit migration PRs move them into `src/web/`, `src/api-runtime/`, or `src/runtime/`. @@ -86,7 +88,8 @@ These legacy transition buckets may remain until explicit migration PRs move the - Root is standard repository configuration and top-level application shells only. - www/ is the browser-served application surface. -- api/ is the Node/API/server application target surface for migration. +- api/ is the Node/API/server application surface. +- Browser-served code must not import top-level `api/` files directly. - src/ is deployable application/runtime/API code. - dev/ is development workspace only. - deploy/ is deployment configuration. diff --git a/dev/build/ProjectInstructions/repository/repository_layout_architecture_plan.md b/dev/build/ProjectInstructions/repository/repository_layout_architecture_plan.md index 1d8c86f8b..2265848ab 100644 --- a/dev/build/ProjectInstructions/repository/repository_layout_architecture_plan.md +++ b/dev/build/ProjectInstructions/repository/repository_layout_architecture_plan.md @@ -1,6 +1,6 @@ # Repository Layout Architecture Plan -Status: Active Scaffold +Status: Active Migration Owner: Owner Scope: Documentation/governance only @@ -22,6 +22,12 @@ This plan does not authorize moving files, changing runtime behavior, changing p No browser, API, server, test, script, or runtime files move in the scaffold or migration-map PRs. +`PR_26180_OWNER_007-www-route-root-compatibility` prepared configurable web-root serving without moving browser files. + +`PR_26180_OWNER_008-move-www-application` moved browser-served application files under `www/` and made local static serving prefer `www/` while preserving public URLs. + +`PR_26180_OWNER_009-move-api-application` moves server/API application runtime under `api/` while preserving `/api/*` route behavior. Browser API client modules remain outside `api/`, and developer-only local startup orchestration remains under `dev/` until the local-runtime migration PR. + ## Proposed Future Layout ```text diff --git a/dev/build/ProjectInstructions/repository/www_migration_map.md b/dev/build/ProjectInstructions/repository/www_migration_map.md index a137d5104..df933d046 100644 --- a/dev/build/ProjectInstructions/repository/www_migration_map.md +++ b/dev/build/ProjectInstructions/repository/www_migration_map.md @@ -107,19 +107,19 @@ These references can be preserved temporarily by serving compatibility paths fro ## Current Local Web Server Root Behavior -Three active server/helper surfaces currently resolve static browser paths from the repository root: +Three active server/helper surfaces currently resolve static browser paths through the shared static route resolver: | File | Current behavior | | --- | --- | -| `dev/scripts/start-dev.mjs` | Team-aware bootstrap static server resolves requests with `path.resolve(repoRoot, \`.\${normalizedPath}\`)`. `/` maps to `/index.html`; `/tools/*` maps to `/toolbox/*`; `/admin/admin-notes.html` maps to `/src/dev-runtime/admin/notes.html`. | -| `src/dev-runtime/server/local-api-server.mjs` | Legacy local API alias serves API routes and falls back to static files from `repoRoot`. `/tools/*` maps to `/toolbox/*`; `/admin/admin-notes.html` maps to `/src/dev-runtime/admin/notes.html`. | -| `dev/tests/helpers/playwrightRepoServer.mjs` | Playwright test server mirrors repo-root static serving and the `/tools/*` and admin-notes compatibility routes. | +| `dev/scripts/start-dev.mjs` | Team-aware bootstrap static server resolves requests with `resolveStaticRouteTarget()`, preferring `www/` while preserving public route URLs and compatibility routes. | +| `api/server/local-api-server.mjs` | Legacy local API alias serves API routes and falls back to `resolveStaticRouteTarget()`, preferring `www/` while preserving public route URLs and compatibility routes. | +| `dev/tests/helpers/playwrightRepoServer.mjs` | Playwright test server mirrors the shared static route resolver and compatibility routes. | -The actual `www/` move must update these filesystem lookup roots or introduce a shared route resolver that can resolve public routes to `www/` while preserving API route ownership. +The actual `www/` move introduced the shared route resolver so public URLs continue to resolve while filesystem ownership lives under `www/`. ## Current Test Assumptions -Playwright and runtime tests currently assume root-based public routes and root-relative filesystem paths: +At the time of the migration map, Playwright and runtime tests assumed root-based public routes and root-relative filesystem paths: - 96 Playwright/helper/runtime files reference public routes such as `/toolbox`, `/account`, `/admin`, `/games`, `/learn`, `/legal`, `/marketplace`, `/memberships`, or `/index.html`. - `dev/tests/playwright/tools/ToolNavigationPrevNext.spec.mjs` opens `/toolbox/index.html` and `/toolbox/game-design/index.html`. @@ -128,7 +128,7 @@ Playwright and runtime tests currently assume root-based public routes and root- - `dev/tests/runtime/V2*` tests frequently assert `toolbox/{tool}/index.html` filesystem or URL behavior. - `dev/scripts/run-node-tests.mjs` and `dev/scripts/run-node-test-files.mjs` register root aliases for `/src/` and `/toolbox/`. -The move PR must update test helpers and route expectations in the same PR that changes the filesystem root. Browser-visible URLs should remain stable unless Owner explicitly approves a public URL change. +The `www/` move PR updated test helpers and route expectations for the filesystem root change. Browser-visible URLs must remain stable unless Owner explicitly approves a public URL change. ## Preserve Versus Rewrite @@ -151,7 +151,6 @@ The move PR must update test helpers and route expectations in the same PR that ### Defer -- Moving server/API code into `api/`. - Moving developer bootstrap into `dev/local-runtime/`. - Removing legacy root compatibility routes. - Changing package commands. diff --git a/dev/build/database/runbook.md b/dev/build/database/runbook.md index d8ac5ada1..06ca8522e 100644 --- a/dev/build/database/runbook.md +++ b/dev/build/database/runbook.md @@ -170,8 +170,8 @@ are stable. It may show validation, apply, backup, restore, and migration history status, but it must not execute database operations from the browser. The status surface currently routes through -`src/dev-runtime/server/local-api-router.mjs`. That filename is retained as a -legacy runtime filename for now; do not infer local database behavior from it. +`api/server/local-api-router.mjs`. That local API filename is retained for now; +do not infer local database behavior from it. ## Rollback Guidance diff --git a/dev/reports/PR_26180_OWNER_009-move-api-application_branch-validation.md b/dev/reports/PR_26180_OWNER_009-move-api-application_branch-validation.md new file mode 100644 index 000000000..fa1c9e61d --- /dev/null +++ b/dev/reports/PR_26180_OWNER_009-move-api-application_branch-validation.md @@ -0,0 +1,23 @@ +# PR_26180_OWNER_009 Branch Validation + +## Startup Validation + +- Project Instructions version: 2026.06.28.009 +- Repository source: PASS +- Cached memory discarded: PASS +- Canonical paths loaded: PASS +- `PROJECT_BRANCHING_POLICY.md` loaded: PASS + +## Branch + +- Current branch: `PR_26180_OWNER_009-move-api-application` +- Expected stacked base: `PR_26180_OWNER_008-move-www-application` +- Base ancestry check: PASS +- Worktree before build: clean on stacked base before branch creation + +## Scope Validation + +- Server/API runtime moved into `api/`: PASS +- Dev-only bootstrap/orchestration not moved: PASS +- Browser/www direct imports of top-level `api/` implementation avoided: PASS +- Runtime/UI product behavior changes avoided: PASS diff --git a/dev/reports/PR_26180_OWNER_009-move-api-application_manual-validation-notes.md b/dev/reports/PR_26180_OWNER_009-move-api-application_manual-validation-notes.md new file mode 100644 index 000000000..809478225 --- /dev/null +++ b/dev/reports/PR_26180_OWNER_009-move-api-application_manual-validation-notes.md @@ -0,0 +1,14 @@ +# PR_26180_OWNER_009 Manual Validation Notes + +## Manual Review + +- Confirmed `src/dev-runtime/` now contains only the Admin Notes browser-viewer compatibility files. +- Confirmed top-level `api/` contains server/API runtime ownership folders. +- Confirmed browser-facing imports use `src/api` client modules rather than top-level `api/` implementation modules. +- Confirmed developer bootstrap files remain under `dev/scripts/` for the later local-runtime migration PR. +- Confirmed active Project Instructions and backlog now describe this API migration step. + +## Manual Route Notes + +- Representative `/api/*` endpoints were exercised through the moved local API server. +- Public URL preservation was checked through the targeted Browser API URL Playwright smoke. diff --git a/dev/reports/PR_26180_OWNER_009-move-api-application_report.md b/dev/reports/PR_26180_OWNER_009-move-api-application_report.md new file mode 100644 index 000000000..a6d78c342 --- /dev/null +++ b/dev/reports/PR_26180_OWNER_009-move-api-application_report.md @@ -0,0 +1,29 @@ +# PR_26180_OWNER_009-move-api-application Report + +## Executive Summary + +PASS. This PR moves server/API application runtime from `src/dev-runtime/` into top-level `api/` while preserving public `/api/*` route behavior. + +The move keeps developer-only local bootstrap/orchestration in `dev/` for the later local-runtime PR. Browser-facing API client modules remain in `src/api/`; `www/` does not import top-level `api/` implementation files directly. + +## Scope Completed + +- Moved Local API server runtime, router, route helpers, services, persistence, database, storage, auth, seed, guest seed, marketplace, membership, legal, messages, project package, team, testing, and toolbox API server modules under `api/`. +- Renamed `src/dev-runtime/DEV_RUNTIME_BOUNDARY.md` to `api/API_RUNTIME_BOUNDARY.md` and updated boundary language. +- Left `src/dev-runtime/admin/` in place as the documented legacy Admin Notes browser-viewer compatibility path. +- Updated dev scripts, targeted tests, Playwright helpers, and active governance docs to reference `api/`. +- Updated Project Instructions version to `2026.06.28.009`. +- Updated `BACKLOG_MASTER.md` to show Repository Architecture Simplification at 40% with next milestone `dev/local-runtime/`. + +## Public Behavior + +- `/api/*` route behavior is preserved. +- Public browser URLs are preserved. +- No product feature behavior was intentionally changed. +- No API endpoint rename was introduced. +- Browser code continues to use API/service contracts through client modules, not direct server implementation imports. + +## Notes + +- The first route smoke attempt included `/api/session/users`, which returned 503 because that route depends on configured provider/session-user data. The final smoke used provider-independent API routes and passed. +- Targeted Playwright initially exposed a stale test-local static server assumption from the prior `www/` move. The spec now uses the shared static route resolver, preserving public routes while serving from `www/`. diff --git a/dev/reports/PR_26180_OWNER_009-move-api-application_requirement-checklist.md b/dev/reports/PR_26180_OWNER_009-move-api-application_requirement-checklist.md new file mode 100644 index 000000000..80d331c15 --- /dev/null +++ b/dev/reports/PR_26180_OWNER_009-move-api-application_requirement-checklist.md @@ -0,0 +1,13 @@ +# PR_26180_OWNER_009 Requirement Checklist + +| Requirement | Status | Evidence | +| --- | --- | --- | +| Base on `PR_26180_OWNER_008-move-www-application` | PASS | Branch ancestry check passed. | +| Move server/API runtime files into `api/` | PASS | Server/router/services/persistence/storage/auth/seed modules moved under `api/`. | +| Preserve `/api/*` route behavior | PASS | Route smoke passed for representative `/api/*` endpoints. | +| Do not move dev-only local runtime/bootstrap orchestration yet | PASS | Bootstrap and startup orchestration remain in `dev/scripts/`. | +| Do not move tests except path/import updates | PASS | Test changes update imports and static route helper assumptions only. | +| Do not change product behavior | PASS | No intentional endpoint or public URL behavior change. | +| Browser/www must not import `api/` files directly | PASS | Browser code continues importing `src/api` client modules; boundary test passes. | +| Update reports under canonical path | PASS | Reports generated under `dev/reports/`. | +| Produce repo-structured ZIP under canonical path | PASS | ZIP generated under `dev/workspace/zips/`. | diff --git a/dev/reports/PR_26180_OWNER_009-move-api-application_validation-report.md b/dev/reports/PR_26180_OWNER_009-move-api-application_validation-report.md new file mode 100644 index 000000000..b78241c05 --- /dev/null +++ b/dev/reports/PR_26180_OWNER_009-move-api-application_validation-report.md @@ -0,0 +1,26 @@ +# PR_26180_OWNER_009 Validation Report + +## Validation Commands + +| Command | Result | +| --- | --- | +| `git diff --check` | PASS | +| `npm run validate:canonical-structure` | PASS | +| `node --check` for changed JS/MJS files | PASS, 86 changed JS/MJS files | +| `node ./dev/scripts/run-node-test-files.mjs dev/tests/dev-runtime/StaticWebRootCompatibility.test.mjs dev/tests/dev-runtime/LocalApiStartupLogging.test.mjs dev/tests/dev-runtime/PublicEnvironmentConfig.test.mjs dev/tests/dev-runtime/DevRuntimeBoundary.test.mjs dev/tests/dev-runtime/AdminNotesBoundary.test.mjs dev/tests/dev-runtime/ArchitectureCleanupApiNavInvitations.test.mjs dev/tests/api/admin-system-health/contract.test.mjs` | PASS, 7/7 files and 30/30 subtests | +| Inline `/api/*` route smoke using `startLocalApiServer()` | PASS | +| `npx playwright test dev/tests/playwright/tools/BrowserApiUrlConfig.spec.mjs --reporter=line` | PASS, 1/1 | + +## Route Smoke Endpoints + +- `/api/runtime/health` - PASS +- `/api/public/config` - PASS +- `/api/session/current` - PASS +- `/api/session/modes` - PASS +- `/api/guest/seed` - PASS +- `/api/providers/contract` - PASS + +## Notes + +- `/api/session/users` was not used in the final smoke because it depends on configured provider/session-user data and returned 503 in this local environment. +- Playwright is targeted because API route behavior and browser API URL handling are adjacent to this move. diff --git a/dev/reports/codex_changed_files.txt b/dev/reports/codex_changed_files.txt index fb58aad6a..f2d871603 100644 Binary files a/dev/reports/codex_changed_files.txt and b/dev/reports/codex_changed_files.txt differ diff --git a/dev/reports/codex_review.diff b/dev/reports/codex_review.diff index e519f102a..5d415d2ae 100644 Binary files a/dev/reports/codex_review.diff and b/dev/reports/codex_review.diff differ diff --git a/dev/scripts/apply-database-seed.mjs b/dev/scripts/apply-database-seed.mjs index 9740ce018..bfab75fd7 100644 --- a/dev/scripts/apply-database-seed.mjs +++ b/dev/scripts/apply-database-seed.mjs @@ -2,9 +2,9 @@ import fs from "node:fs"; import path from "node:path"; import process from "node:process"; -import { SupabasePostgresProviderAdapter } from "../../src/dev-runtime/auth/provider-contract-stubs.mjs"; -import { SEED_DB_KEYS } from "../../src/dev-runtime/seed/seed-db-keys.mjs"; -import { syncSupabaseDevCreatorIdentities } from "../../src/dev-runtime/testing/supabase-dev-creator-identity-seed-sync.mjs"; +import { SupabasePostgresProviderAdapter } from "../../api/auth/provider-contract-stubs.mjs"; +import { SEED_DB_KEYS } from "../../api/seed/seed-db-keys.mjs"; +import { syncSupabaseDevCreatorIdentities } from "../../api/testing/supabase-dev-creator-identity-seed-sync.mjs"; const ENV_FILE = ".env"; const DEV_DATABASE_NAME = "gamefoundry_dev"; diff --git a/dev/scripts/cleanup-supabase-dev-auth-test-users.mjs b/dev/scripts/cleanup-supabase-dev-auth-test-users.mjs index 41aef024f..08ee2b234 100644 --- a/dev/scripts/cleanup-supabase-dev-auth-test-users.mjs +++ b/dev/scripts/cleanup-supabase-dev-auth-test-users.mjs @@ -2,7 +2,7 @@ import { existsSync, readFileSync } from "node:fs"; import path from "node:path"; import process from "node:process"; -import { cleanupSupabaseDevAuthTestUsers } from "../../src/dev-runtime/testing/supabase-dev-auth-test-user-cleanup.mjs"; +import { cleanupSupabaseDevAuthTestUsers } from "../../api/testing/supabase-dev-auth-test-user-cleanup.mjs"; function parseEnvValue(value) { const trimmed = value.trim(); diff --git a/dev/scripts/database-migration-runner.mjs b/dev/scripts/database-migration-runner.mjs index f018fbd66..177efb69d 100644 --- a/dev/scripts/database-migration-runner.mjs +++ b/dev/scripts/database-migration-runner.mjs @@ -2,7 +2,7 @@ import crypto from "node:crypto"; import fs from "node:fs"; import path from "node:path"; import process from "node:process"; -import { createPostgresConnectionClient, databaseSslMode } from "../../src/dev-runtime/persistence/postgres-connection-client.mjs"; +import { createPostgresConnectionClient, databaseSslMode } from "../../api/persistence/postgres-connection-client.mjs"; const ENV_FILE = ".env"; const PREFERRED_GROUP_ORDER = Object.freeze([ diff --git a/dev/scripts/start-dev.mjs b/dev/scripts/start-dev.mjs index 33e8420a8..1dd8ce4f6 100644 --- a/dev/scripts/start-dev.mjs +++ b/dev/scripts/start-dev.mjs @@ -5,9 +5,9 @@ import http from "node:http"; import path from "node:path"; import process from "node:process"; import { fileURLToPath, pathToFileURL } from "node:url"; -import { localAdminNotesHeaderPartialPath } from "../../src/dev-runtime/admin/admin-notes-menu.mjs"; -import { startLocalApiServer } from "../../src/dev-runtime/server/local-api-server.mjs"; -import { resolveStaticRouteTarget } from "../../src/dev-runtime/server/static-web-root.mjs"; +import { localAdminNotesHeaderPartialPath } from "../../api/admin/admin-notes-menu.mjs"; +import { startLocalApiServer } from "../../api/server/local-api-server.mjs"; +import { resolveStaticRouteTarget } from "../../api/server/static-web-root.mjs"; import { parseRoleArgument, parseTeamArgument, diff --git a/dev/scripts/start-local-api-server.mjs b/dev/scripts/start-local-api-server.mjs index a384409ae..0c1e9964a 100644 --- a/dev/scripts/start-local-api-server.mjs +++ b/dev/scripts/start-local-api-server.mjs @@ -2,9 +2,9 @@ import process from "node:process"; import { existsSync, readFileSync } from "node:fs"; import path from "node:path"; import { pathToFileURL } from "node:url"; -import { databaseSslMode } from "../../src/dev-runtime/persistence/postgres-connection-client.mjs"; -import { startLocalApiServer } from "../../src/dev-runtime/server/local-api-server.mjs"; -import { loadStorageConfig } from "../../src/dev-runtime/storage/storage-config.mjs"; +import { databaseSslMode } from "../../api/persistence/postgres-connection-client.mjs"; +import { startLocalApiServer } from "../../api/server/local-api-server.mjs"; +import { loadStorageConfig } from "../../api/storage/storage-config.mjs"; const RUNTIME_ENV_FILE = ".env"; const NOT_CONFIGURED = "(not configured)"; diff --git a/dev/scripts/sync-supabase-dev-creator-identities.mjs b/dev/scripts/sync-supabase-dev-creator-identities.mjs index 31bcc5f08..a9b3b9253 100644 --- a/dev/scripts/sync-supabase-dev-creator-identities.mjs +++ b/dev/scripts/sync-supabase-dev-creator-identities.mjs @@ -2,7 +2,7 @@ import { existsSync, readFileSync } from "node:fs"; import path from "node:path"; import process from "node:process"; -import { syncSupabaseDevCreatorIdentities } from "../../src/dev-runtime/testing/supabase-dev-creator-identity-seed-sync.mjs"; +import { syncSupabaseDevCreatorIdentities } from "../../api/testing/supabase-dev-creator-identity-seed-sync.mjs"; function parseEnvValue(value) { const trimmed = value.trim(); diff --git a/dev/scripts/validate-browser-env-agnostic.mjs b/dev/scripts/validate-browser-env-agnostic.mjs index 64232b2f0..ccbbab47d 100644 --- a/dev/scripts/validate-browser-env-agnostic.mjs +++ b/dev/scripts/validate-browser-env-agnostic.mjs @@ -4,14 +4,15 @@ import path from "node:path"; const repoRoot = process.cwd(); const reportPath = path.join(repoRoot, "dev", "reports", "environment_agnostic_browser_gate_report.md"); const browserScanRoots = [ - "account", - "admin", + "www/account", + "www/admin", "www/assets/theme-v2/js", - "toolbox", + "www/toolbox", "src/engine", ]; const environmentScanRoots = [ ...browserScanRoots, + "api", "src", "dev/scripts", "dev/build/database", @@ -112,7 +113,7 @@ function isExcluded(absolutePath) { function isValidationOrTestException(filePath) { const normalizedPath = repoPath(filePath); return normalizedPath.startsWith("dev/tests/") || - normalizedPath.startsWith("src/dev-runtime/testing/") || + normalizedPath.startsWith("api/testing/") || /^dev\/scripts\/validate-[^/]+\.mjs$/.test(normalizedPath) || /^dev\/scripts\/cleanup-supabase-dev-auth-test-users\.mjs$/.test(normalizedPath) || /^dev\/scripts\/sync-supabase-dev-creator-identities\.mjs$/.test(normalizedPath); @@ -328,15 +329,15 @@ async function validateProductServiceContract() { rejectPattern(contents, filePath, providerLeakPattern, findings, "Product API client must not expose provider/environment implementation details."); } - const router = await readRequiredRepoFile("src/dev-runtime/server/local-api-router.mjs", findings, "Local API router is missing"); - requireSnippet(router, "src/dev-runtime/server/local-api-router.mjs", "async toolRegistrySnapshotForRoute() {\n this.supabaseDatabaseAdapter(\"Reading Toolbox registry\");", findings, "Toolbox registry route must require the configured server product-data adapter."); - requireSnippet(router, "src/dev-runtime/server/local-api-router.mjs", "async toolboxVoteSnapshotForRoute() {\n this.supabaseDatabaseAdapter(\"Reading Supabase Toolbox vote snapshot\");", findings, "Toolbox vote route must require the configured server product-data adapter."); - requireSnippet(router, "src/dev-runtime/server/local-api-router.mjs", "async snapshotForRoute() {\n const adapter = this.supabaseDatabaseAdapter(\"Reading Supabase product database state\");", findings, "DB snapshot route must read the configured server product-data adapter."); - requireSnippet(router, "src/dev-runtime/server/local-api-router.mjs", "if (parts[1] === \"product-data\" && request.method === \"GET\" && parts[2] === \"snapshot\")", findings, "Product data snapshots must use the service-contract route name."); - requireSnippet(router, "src/dev-runtime/server/local-api-router.mjs", "this.assertProductDatabaseProvider(`Creating ${toolId} repository`);", findings, "Repository creation must assert the server-owned product-data contract."); - requireSnippet(router, "src/dev-runtime/server/local-api-router.mjs", "this.assertProductDatabaseProvider(`Calling repository method ${methodName}`);", findings, "Repository method calls must assert the server-owned product-data contract."); - rejectPattern(router, "src/dev-runtime/server/local-api-router.mjs", /selectedDatabaseProviderId|selectedAuthProvider|selectedProvidersCanServeRuntime/, findings, "Runtime router must not contain active provider-selection helpers."); - rejectPattern(router, "src/dev-runtime/server/local-api-router.mjs", routerRetiredStoragePattern, findings, "Runtime router must not contain retired file-DB startup/opening code, provider-selection environment variables, or retired local-db/mock-db routes."); + const router = await readRequiredRepoFile("api/server/local-api-router.mjs", findings, "Local API router is missing"); + requireSnippet(router, "api/server/local-api-router.mjs", "async toolRegistrySnapshotForRoute() {\n this.supabaseDatabaseAdapter(\"Reading Toolbox registry\");", findings, "Toolbox registry route must require the configured server product-data adapter."); + requireSnippet(router, "api/server/local-api-router.mjs", "async toolboxVoteSnapshotForRoute() {\n this.supabaseDatabaseAdapter(\"Reading Supabase Toolbox vote snapshot\");", findings, "Toolbox vote route must require the configured server product-data adapter."); + requireSnippet(router, "api/server/local-api-router.mjs", "async snapshotForRoute() {\n const adapter = this.supabaseDatabaseAdapter(\"Reading Supabase product database state\");", findings, "DB snapshot route must read the configured server product-data adapter."); + requireSnippet(router, "api/server/local-api-router.mjs", "if (parts[1] === \"product-data\" && request.method === \"GET\" && parts[2] === \"snapshot\")", findings, "Product data snapshots must use the service-contract route name."); + requireSnippet(router, "api/server/local-api-router.mjs", "this.assertProductDatabaseProvider(`Creating ${toolId} repository`);", findings, "Repository creation must assert the server-owned product-data contract."); + requireSnippet(router, "api/server/local-api-router.mjs", "this.assertProductDatabaseProvider(`Calling repository method ${methodName}`);", findings, "Repository method calls must assert the server-owned product-data contract."); + rejectPattern(router, "api/server/local-api-router.mjs", /selectedDatabaseProviderId|selectedAuthProvider|selectedProvidersCanServeRuntime/, findings, "Runtime router must not contain active provider-selection helpers."); + rejectPattern(router, "api/server/local-api-router.mjs", routerRetiredStoragePattern, findings, "Runtime router must not contain retired file-DB startup/opening code, provider-selection environment variables, or retired local-db/mock-db routes."); const startup = await readRequiredRepoFile("dev/scripts/start-local-api-server.mjs", findings, "Local API startup script is missing"); rejectPattern(startup, "dev/scripts/start-local-api-server.mjs", /GAMEFOUNDRY_AUTH_PROVIDER|GAMEFOUNDRY_DB_PROVIDER|auth provider|product data provider|provider selection/i, findings, "Local API startup must describe configured connections without provider-selection environment variables."); diff --git a/dev/scripts/validate-database-drift.mjs b/dev/scripts/validate-database-drift.mjs index af28c4b9b..8b121919f 100644 --- a/dev/scripts/validate-database-drift.mjs +++ b/dev/scripts/validate-database-drift.mjs @@ -2,7 +2,7 @@ import fs from "node:fs"; import path from "node:path"; import process from "node:process"; -import { createPostgresConnectionClient } from "../../src/dev-runtime/persistence/postgres-connection-client.mjs"; +import { createPostgresConnectionClient } from "../../api/persistence/postgres-connection-client.mjs"; const ENV_FILE = ".env"; const DDL_DIRECTORY = "dev/build/database/ddl"; diff --git a/dev/scripts/validate-dev-runtime-boundary.mjs b/dev/scripts/validate-dev-runtime-boundary.mjs index 7406517d2..51cefc332 100644 --- a/dev/scripts/validate-dev-runtime-boundary.mjs +++ b/dev/scripts/validate-dev-runtime-boundary.mjs @@ -3,27 +3,32 @@ import path from "node:path"; const repoRoot = process.cwd(); const roots = [ - "account", - "admin", - "assets", - "company", - "community", - "games", - "legal", - "marketplace", - "memberships", - "owner", + "www/account", + "www/admin", + "www/assets", + "www/company", + "www/community", + "www/games", + "www/legal", + "www/marketplace", + "www/memberships", + "www/owner", "src/api", "src/engine", - "toolbox", + "www/toolbox", ]; const filePattern = /\.(html|js|mjs)$/; const forbiddenPatterns = [ /src\/dev-runtime/, /src\\dev-runtime/, + /from\s+["'][^"']*(?:\.\.?\/)+api\//, + /import\(["'][^"']*(?:\.\.?\/)+api\//, /from\s+["'][^"']*\.\.\/dev-runtime\//, /import\(["'][^"']*\.\.\/dev-runtime\//, ]; +const allowedFindings = new Set([ + "www/owner/notes.html", +]); const findings = []; function walk(dirPath) { @@ -42,16 +47,17 @@ function walk(dirPath) { for (const root of roots) { for (const filePath of walk(path.join(repoRoot, root))) { const source = fs.readFileSync(filePath, "utf8"); - if (forbiddenPatterns.some((pattern) => pattern.test(source))) { - findings.push(path.relative(repoRoot, filePath).replaceAll("\\", "/")); + const relativeFilePath = path.relative(repoRoot, filePath).replaceAll("\\", "/"); + if (forbiddenPatterns.some((pattern) => pattern.test(source)) && !allowedFindings.has(relativeFilePath)) { + findings.push(relativeFilePath); } } } if (findings.length) { - console.error("FAIL: UAT/PROD-facing files import or reference src/dev-runtime:"); + console.error("FAIL: UAT/PROD-facing files import or reference local API runtime implementation:"); findings.forEach((finding) => console.error(`- ${finding}`)); process.exit(1); } -console.log("PASS: UAT/PROD-facing browser/runtime files do not import or bundle src/dev-runtime."); +console.log("PASS: UAT/PROD-facing browser/runtime files do not import or bundle local API runtime implementation."); diff --git a/dev/scripts/validate-local-postgres-runtime.mjs b/dev/scripts/validate-local-postgres-runtime.mjs index a5b4c4b6b..e8ee1ba67 100644 --- a/dev/scripts/validate-local-postgres-runtime.mjs +++ b/dev/scripts/validate-local-postgres-runtime.mjs @@ -3,11 +3,11 @@ import fs from "node:fs"; import http from "node:http"; import path from "node:path"; import process from "node:process"; -import { createProviderContractSnapshot, SupabasePostgresProviderAdapter } from "../../src/dev-runtime/auth/provider-contract-stubs.mjs"; -import { createPostgresConnectionClient } from "../../src/dev-runtime/persistence/postgres-connection-client.mjs"; -import { createLocalApiRouter } from "../../src/dev-runtime/server/local-api-router.mjs"; -import { createServerSeedTables } from "../../src/dev-runtime/seed/server-seed-loader.mjs"; -import { SEED_DB_KEYS } from "../../src/dev-runtime/seed/seed-db-keys.mjs"; +import { createProviderContractSnapshot, SupabasePostgresProviderAdapter } from "../../api/auth/provider-contract-stubs.mjs"; +import { createPostgresConnectionClient } from "../../api/persistence/postgres-connection-client.mjs"; +import { createLocalApiRouter } from "../../api/server/local-api-router.mjs"; +import { createServerSeedTables } from "../../api/seed/server-seed-loader.mjs"; +import { SEED_DB_KEYS } from "../../api/seed/seed-db-keys.mjs"; const RUNTIME_ENV_FILE = ".env"; const DDL_FILES = Object.freeze([ diff --git a/dev/scripts/validate-runtime-connections.mjs b/dev/scripts/validate-runtime-connections.mjs index b94e4f09e..e74ba539c 100644 --- a/dev/scripts/validate-runtime-connections.mjs +++ b/dev/scripts/validate-runtime-connections.mjs @@ -6,7 +6,7 @@ import path from "node:path"; import process from "node:process"; import tls from "node:tls"; import { URL } from "node:url"; -import { createPostgresConnectionClient, databaseSslMode } from "../../src/dev-runtime/persistence/postgres-connection-client.mjs"; +import { createPostgresConnectionClient, databaseSslMode } from "../../api/persistence/postgres-connection-client.mjs"; const ENV_FILE = ".env"; const REQUIRED_ENV = Object.freeze([ diff --git a/dev/scripts/validate-storage-config.mjs b/dev/scripts/validate-storage-config.mjs index 81d5152d9..01f3d9961 100644 --- a/dev/scripts/validate-storage-config.mjs +++ b/dev/scripts/validate-storage-config.mjs @@ -2,12 +2,12 @@ import fs from "node:fs"; import path from "node:path"; import process from "node:process"; -import { createConfiguredProjectAssetStorage } from "../../src/dev-runtime/storage/r2-project-asset-storage.mjs"; +import { createConfiguredProjectAssetStorage } from "../../api/storage/r2-project-asset-storage.mjs"; import { STORAGE_ENV_KEYS, STORAGE_PROJECTS_ALLOWED_PREFIXES, loadStorageConfig, -} from "../../src/dev-runtime/storage/storage-config.mjs"; +} from "../../api/storage/storage-config.mjs"; const ENV_FILE = ".env"; diff --git a/dev/tests/api/admin-system-health/contract.test.mjs b/dev/tests/api/admin-system-health/contract.test.mjs index fb803c1da..0138c0bac 100644 --- a/dev/tests/api/admin-system-health/contract.test.mjs +++ b/dev/tests/api/admin-system-health/contract.test.mjs @@ -1,8 +1,8 @@ import http from "node:http"; import test from "node:test"; import assert from "node:assert/strict"; -import { createLocalApiRouter } from "../../../../src/dev-runtime/server/local-api-router.mjs"; -import { SEED_DB_KEYS } from "../../../../src/dev-runtime/seed/seed-db-keys.mjs"; +import { createLocalApiRouter } from "../../../../api/server/local-api-router.mjs"; +import { SEED_DB_KEYS } from "../../../../api/seed/seed-db-keys.mjs"; function withEnv(nextEnv, callback) { const previousEnv = {}; diff --git a/dev/tests/dev-runtime/AdminHealthOperations.test.mjs b/dev/tests/dev-runtime/AdminHealthOperations.test.mjs index c79470c3f..36a5e483e 100644 --- a/dev/tests/dev-runtime/AdminHealthOperations.test.mjs +++ b/dev/tests/dev-runtime/AdminHealthOperations.test.mjs @@ -4,14 +4,14 @@ import assert from "node:assert/strict"; import { adminOperationsHealth, createLocalApiRouter, -} from "../../../src/dev-runtime/server/local-api-router.mjs"; +} from "../../../api/server/local-api-router.mjs"; import { debitAiCreditsForAction, grantMonthlyAiCredits, -} from "../../../src/dev-runtime/ai/ai-credit-service.mjs"; -import { assignUserMembership } from "../../../src/dev-runtime/memberships/membership-assignment-service.mjs"; -import { SEED_DB_KEYS, makeSeedUlid } from "../../../src/dev-runtime/seed/seed-db-keys.mjs"; -import { createServerSeedTables } from "../../../src/dev-runtime/seed/server-seed-loader.mjs"; +} from "../../../api/ai/ai-credit-service.mjs"; +import { assignUserMembership } from "../../../api/memberships/membership-assignment-service.mjs"; +import { SEED_DB_KEYS, makeSeedUlid } from "../../../api/seed/seed-db-keys.mjs"; +import { createServerSeedTables } from "../../../api/seed/server-seed-loader.mjs"; function createKeyFactory(start = 12000) { let sequence = start; diff --git a/dev/tests/dev-runtime/AdminNotesBoundary.test.mjs b/dev/tests/dev-runtime/AdminNotesBoundary.test.mjs index c3c638959..ca041fa9d 100644 --- a/dev/tests/dev-runtime/AdminNotesBoundary.test.mjs +++ b/dev/tests/dev-runtime/AdminNotesBoundary.test.mjs @@ -3,24 +3,24 @@ import fs from "node:fs"; import path from "node:path"; import process from "node:process"; import test from "node:test"; -import { handleAdminNotesDirectoryApiRequest } from "../../../src/dev-runtime/admin/admin-notes-directory.mjs"; +import { handleAdminNotesDirectoryApiRequest } from "../../../api/admin/admin-notes-directory.mjs"; import { ADMIN_NOTES_LOCAL_MENU_LABEL, ADMIN_NOTES_LOCAL_SOURCE_PATH, ADMIN_NOTES_LOCAL_VIEWER_PATH, ADMIN_MY_STUFF_MENU_LABEL, localAdminNotesHeaderPartialPath, -} from "../../../src/dev-runtime/admin/admin-notes-menu.mjs"; +} from "../../../api/admin/admin-notes-menu.mjs"; const repoRoot = process.cwd(); const productionRoots = [ - "account", - "admin", - "assets", - "owner", + "www/account", + "www/admin", + "www/assets", + "www/owner", "src/engine", "src/shared", - "toolbox", + "www/toolbox", ]; const expectedDevNotes = [ @@ -36,10 +36,10 @@ const expectedDevNotes = [ ]; const retiredProductionFiles = [ - "admin/notes.html", + "www/admin/notes.html", "src/dev-runtime/admin/admin-notes.html", - "admin/notes/index.txt", - "admin/notes/other/index.txt", + "www/admin/notes/index.txt", + "www/admin/notes/other/index.txt", "dev/archive/legacy-docs-build/admin-notes/notes/Other/index.txt", ]; @@ -149,21 +149,21 @@ test("Admin Notes dev files and local viewer entrypoint exist", () => { }); }); -test("Admin Notes implementation is isolated under src/dev-runtime/admin", () => { +test("Admin Notes browser viewer stays under src/dev-runtime/admin while server helpers live under api/admin", () => { assert.equal( fs.existsSync(repoPath("src/dev-runtime/admin/admin-notes-viewer.js")), true, - "dev-runtime Admin Notes viewer exists", + "legacy Admin Notes viewer exists", ); assert.equal( - fs.existsSync(repoPath("src/dev-runtime/admin/admin-notes-directory.mjs")), + fs.existsSync(repoPath("api/admin/admin-notes-directory.mjs")), true, - "dev-runtime Admin Notes directory handler exists", + "API Admin Notes directory handler exists", ); assert.equal( - fs.existsSync(repoPath("src/dev-runtime/admin/admin-notes-menu.mjs")), + fs.existsSync(repoPath("api/admin/admin-notes-menu.mjs")), true, - "dev-runtime Admin Notes local menu route helper exists", + "API Admin Notes local menu route helper exists", ); assert.equal( fs.existsSync(repoPath("src/dev-runtime/admin/header-nav.local.html")), @@ -188,7 +188,7 @@ test("Admin Notes local viewer page uses external dev-runtime JavaScript only", }); test("Owner Notes route is the only production-facing Admin Notes viewer route", () => { - const ownerNotesSource = fs.readFileSync(repoPath("owner/notes.html"), "utf8"); + const ownerNotesSource = fs.readFileSync(repoPath("www/owner/notes.html"), "utf8"); assert.doesNotMatch(ownerNotesSource, /]*\bsrc=)/i, "Owner Notes page must not contain inline scripts"); assert.doesNotMatch(ownerNotesSource, / assert.doesNotMatch(servedHeader, new RegExp(`>${ADMIN_NOTES_LOCAL_MENU_LABEL}<\\/a>`)); assert.doesNotMatch(servedHeader, new RegExp(`>${ADMIN_MY_STUFF_MENU_LABEL}<\\/a>`)); assert.doesNotMatch(source, /data-admin-notes-local-menu|Admin Notes/); - assert.equal(localAdminNotesHeaderPartialPath(repoRoot, repoPath("account/sign-in.html")), repoPath("account/sign-in.html")); + assert.equal(localAdminNotesHeaderPartialPath(repoRoot, repoPath("www/account/sign-in.html")), repoPath("www/account/sign-in.html")); }); test("Admin page left menus use dynamic placeholders without Notes duplication", () => { - const adminDir = repoPath("admin"); + const adminDir = repoPath("www/admin"); const pages = fs.readdirSync(adminDir).filter((name) => name.endsWith(".html")).sort(); const checkedPages = []; diff --git a/dev/tests/dev-runtime/AiCreditDisplay.test.mjs b/dev/tests/dev-runtime/AiCreditDisplay.test.mjs index 30393d5b1..65857ae59 100644 --- a/dev/tests/dev-runtime/AiCreditDisplay.test.mjs +++ b/dev/tests/dev-runtime/AiCreditDisplay.test.mjs @@ -1,11 +1,11 @@ import http from "node:http"; import test from "node:test"; import assert from "node:assert/strict"; -import { createLocalApiRouter } from "../../../src/dev-runtime/server/local-api-router.mjs"; -import { grantMonthlyAiCredits, debitAiCreditsForAction, readAiCreditDisplay } from "../../../src/dev-runtime/ai/ai-credit-service.mjs"; -import { assignUserMembership } from "../../../src/dev-runtime/memberships/membership-assignment-service.mjs"; -import { SEED_DB_KEYS, makeSeedUlid } from "../../../src/dev-runtime/seed/seed-db-keys.mjs"; -import { createServerSeedTables } from "../../../src/dev-runtime/seed/server-seed-loader.mjs"; +import { createLocalApiRouter } from "../../../api/server/local-api-router.mjs"; +import { grantMonthlyAiCredits, debitAiCreditsForAction, readAiCreditDisplay } from "../../../api/ai/ai-credit-service.mjs"; +import { assignUserMembership } from "../../../api/memberships/membership-assignment-service.mjs"; +import { SEED_DB_KEYS, makeSeedUlid } from "../../../api/seed/seed-db-keys.mjs"; +import { createServerSeedTables } from "../../../api/seed/server-seed-loader.mjs"; function createKeyFactory(start = 1500) { let sequence = start; diff --git a/dev/tests/dev-runtime/AiCreditFoundation.test.mjs b/dev/tests/dev-runtime/AiCreditFoundation.test.mjs index 7327a754d..7363f571a 100644 --- a/dev/tests/dev-runtime/AiCreditFoundation.test.mjs +++ b/dev/tests/dev-runtime/AiCreditFoundation.test.mjs @@ -1,11 +1,11 @@ import test from "node:test"; import assert from "node:assert/strict"; -import { SUPABASE_POSTGRES_PRODUCT_TABLES } from "../../../src/dev-runtime/auth/provider-contract-stubs.mjs"; -import { debitAiCreditsForAction, grantMonthlyAiCredits, purchaseAiCreditPack } from "../../../src/dev-runtime/ai/ai-credit-service.mjs"; -import { assignUserMembership } from "../../../src/dev-runtime/memberships/membership-assignment-service.mjs"; -import { getMockDbTableSchemas } from "../../../src/dev-runtime/persistence/mock-db-store.js"; -import { SEED_DB_KEYS, makeSeedUlid } from "../../../src/dev-runtime/seed/seed-db-keys.mjs"; -import { createServerSeedTables } from "../../../src/dev-runtime/seed/server-seed-loader.mjs"; +import { SUPABASE_POSTGRES_PRODUCT_TABLES } from "../../../api/auth/provider-contract-stubs.mjs"; +import { debitAiCreditsForAction, grantMonthlyAiCredits, purchaseAiCreditPack } from "../../../api/ai/ai-credit-service.mjs"; +import { assignUserMembership } from "../../../api/memberships/membership-assignment-service.mjs"; +import { getMockDbTableSchemas } from "../../../api/persistence/mock-db-store.js"; +import { SEED_DB_KEYS, makeSeedUlid } from "../../../api/seed/seed-db-keys.mjs"; +import { createServerSeedTables } from "../../../api/seed/server-seed-loader.mjs"; function createKeyFactory(start = 1500) { let sequence = start; diff --git a/dev/tests/dev-runtime/ArchitectureCleanupApiNavInvitations.test.mjs b/dev/tests/dev-runtime/ArchitectureCleanupApiNavInvitations.test.mjs index 320c53ec0..a2bdd03d6 100644 --- a/dev/tests/dev-runtime/ArchitectureCleanupApiNavInvitations.test.mjs +++ b/dev/tests/dev-runtime/ArchitectureCleanupApiNavInvitations.test.mjs @@ -2,12 +2,12 @@ import http from "node:http"; import test from "node:test"; import assert from "node:assert/strict"; -import { createLocalApiRouter } from "../../../src/dev-runtime/server/local-api-router.mjs"; +import { createLocalApiRouter } from "../../../api/server/local-api-router.mjs"; import { getAdminNavigationItems, getOwnerNavigationItems, } from "../../../src/api/admin-owner-navigation.js"; -import { SEED_DB_KEYS } from "../../../src/dev-runtime/seed/seed-db-keys.mjs"; +import { SEED_DB_KEYS } from "../../../api/seed/seed-db-keys.mjs"; const MOVED_API_CLIENTS = Object.freeze([ "admin-infrastructure-api-client.js", @@ -81,7 +81,7 @@ async function apiJson(baseUrl, pathName, request = {}) { } test("product and web API clients live under src/api while engine API keeps only shared server plumbing", () => { - assert.deepEqual(fs.readdirSync("src/engine/api").sort(), []); + assert.equal(fs.existsSync("src/engine/api"), false); assert.equal(fs.existsSync("src/api/server-api-client.js"), true); MOVED_API_CLIENTS.forEach((fileName) => { assert.equal(fs.existsSync(`src/api/${fileName}`), true, `${fileName} should live under src/api`); @@ -120,26 +120,26 @@ test("Admin and Owner navigation are shared and include present operational/busi test("touched Admin and Owner pages do not duplicate sidebar navigation links", () => { [ - "admin/invitations.html", - "admin/system-health.html", - "admin/infrastructure.html", - "admin/environments.html", - "admin/game-migration.html", - "admin/platform-settings.html", - "admin/site-setup.html", - "admin/tool-votes.html", - "admin/users.html", - "owner/ai-credits.html", - "owner/branding.html", - "owner/design-system.html", - "owner/grouping-colors.html", - "owner/memberships.html", - "owner/site-settings.html", - "owner/themes.html", + "www/admin/invitations.html", + "www/admin/system-health.html", + "www/admin/infrastructure.html", + "www/admin/environments.html", + "www/admin/game-migration.html", + "www/admin/platform-settings.html", + "www/admin/site-setup.html", + "www/admin/tool-votes.html", + "www/admin/users.html", + "www/owner/ai-credits.html", + "www/owner/branding.html", + "www/owner/design-system.html", + "www/owner/grouping-colors.html", + "www/owner/memberships.html", + "www/owner/site-settings.html", + "www/owner/themes.html", ].forEach((fileName) => { const source = fs.readFileSync(fileName, "utf8"); assert.equal(source.includes("assets/theme-v2/js/admin-owner-navigation.js"), true, `${fileName} should load shared nav renderer`); - if (fileName.startsWith("owner/")) { + if (fileName.startsWith("www/owner/")) { assert.match(source, /data-owner-tool-menu/); assert.equal(source.includes("href=\"/owner/memberships.html\""), false); } else { @@ -149,18 +149,18 @@ test("touched Admin and Owner pages do not duplicate sidebar navigation links", }); }); -test("dev-runtime boundary is documented for runtime implementation and not test ownership", () => { - const source = fs.readFileSync("src/dev-runtime/DEV_RUNTIME_BOUNDARY.md", "utf8"); - assert.match(source, /dev-only runtime implementation|local development runtime implementation/i); - assert.match(source, /not `tests\/dev-runtime`/); - assert.match(source, /UAT and PROD bundles must not import, bundle, or deploy `src\/dev-runtime`/); +test("API runtime boundary is documented for runtime implementation and not test ownership", () => { + const source = fs.readFileSync("api/API_RUNTIME_BOUNDARY.md", "utf8"); + assert.match(source, /server\/API application runtime implementation/i); + assert.match(source, /not `dev\/tests\/dev-runtime`/); + assert.match(source, /Browser pages, Theme V2 scripts, toolbox pages, and `src\/engine` runtime code must use declared API\/service contracts instead of importing `api\/` directly/); }); test("Toolbox registry consumes shared metadata without importing dev-runtime", () => { const registrySource = fs.readFileSync("www/toolbox/toolRegistry.js", "utf8"); - const devRuntimeShim = fs.readFileSync("src/dev-runtime/guest-seeds/tool-metadata-inventory.js", "utf8"); + const devRuntimeShim = fs.readFileSync("api/guest-seeds/tool-metadata-inventory.js", "utf8"); assert.match(registrySource, /src\/shared\/toolbox\/tool-metadata-inventory\.js/); assert.doesNotMatch(registrySource, /src\/dev-runtime|src\\dev-runtime|dev-runtime\/guest-seeds/); - assert.match(devRuntimeShim, /\.\.\/\.\.\/shared\/toolbox\/tool-metadata-inventory\.js/); + assert.match(devRuntimeShim, /\.\.\/\.\.\/src\/shared\/toolbox\/tool-metadata-inventory\.js/); assert.equal(fs.existsSync("src/shared/toolbox/tool-metadata-inventory.js"), true); }); diff --git a/dev/tests/dev-runtime/BetaInvitationsAdmin.test.mjs b/dev/tests/dev-runtime/BetaInvitationsAdmin.test.mjs index fce986955..0f77ebe21 100644 --- a/dev/tests/dev-runtime/BetaInvitationsAdmin.test.mjs +++ b/dev/tests/dev-runtime/BetaInvitationsAdmin.test.mjs @@ -1,8 +1,8 @@ import http from "node:http"; import test from "node:test"; import assert from "node:assert/strict"; -import { createLocalApiRouter } from "../../../src/dev-runtime/server/local-api-router.mjs"; -import { SEED_DB_KEYS } from "../../../src/dev-runtime/seed/seed-db-keys.mjs"; +import { createLocalApiRouter } from "../../../api/server/local-api-router.mjs"; +import { SEED_DB_KEYS } from "../../../api/seed/seed-db-keys.mjs"; function withEnv(nextEnv, callback) { const previousEnv = {}; diff --git a/dev/tests/dev-runtime/DbSeedIntegrity.test.mjs b/dev/tests/dev-runtime/DbSeedIntegrity.test.mjs index 5484a40ab..5dd1fcfc3 100644 --- a/dev/tests/dev-runtime/DbSeedIntegrity.test.mjs +++ b/dev/tests/dev-runtime/DbSeedIntegrity.test.mjs @@ -4,9 +4,9 @@ import path from "node:path"; import process from "node:process"; import test from "node:test"; import assert from "node:assert/strict"; -import { createLocalApiRouter } from "../../../src/dev-runtime/server/local-api-router.mjs"; -import { MOCK_DB_KEYS } from "../../../src/dev-runtime/persistence/mock-db-store.js"; -import { getActiveToolRegistry } from "../../../src/dev-runtime/guest-seeds/tool-metadata-inventory.js"; +import { createLocalApiRouter } from "../../../api/server/local-api-router.mjs"; +import { MOCK_DB_KEYS } from "../../../api/persistence/mock-db-store.js"; +import { getActiveToolRegistry } from "../../../api/guest-seeds/tool-metadata-inventory.js"; import { createMessagesPostgresClientStub } from "../helpers/messagesPostgresClientStub.mjs"; const GUEST_SEED_GROUP_KEYS = getActiveToolRegistry() diff --git a/dev/tests/dev-runtime/DbViewerConfiguredSnapshot.test.mjs b/dev/tests/dev-runtime/DbViewerConfiguredSnapshot.test.mjs index 8f8bd4216..d2dbe6f26 100644 --- a/dev/tests/dev-runtime/DbViewerConfiguredSnapshot.test.mjs +++ b/dev/tests/dev-runtime/DbViewerConfiguredSnapshot.test.mjs @@ -1,6 +1,6 @@ import test from "node:test"; import assert from "node:assert/strict"; -import { SupabasePostgresProviderAdapter } from "../../../src/dev-runtime/auth/provider-contract-stubs.mjs"; +import { SupabasePostgresProviderAdapter } from "../../../api/auth/provider-contract-stubs.mjs"; test("DB Viewer configured snapshot keeps schema-known tables visible when one configured table is missing", async () => { const calls = []; diff --git a/dev/tests/dev-runtime/DevRuntimeBoundary.test.mjs b/dev/tests/dev-runtime/DevRuntimeBoundary.test.mjs index 6fccb3294..22ddd4448 100644 --- a/dev/tests/dev-runtime/DevRuntimeBoundary.test.mjs +++ b/dev/tests/dev-runtime/DevRuntimeBoundary.test.mjs @@ -6,41 +6,43 @@ import assert from "node:assert/strict"; const repoRoot = process.cwd(); const browserSurfaceRoots = [ - "account", - "admin", - "assets", + "www/account", + "www/admin", + "www/assets", + "www/owner", "src/engine", "src/shared", - "toolbox", + "www/toolbox", ]; const movedDevRuntimeFiles = [ - "src/dev-runtime/guest-seeds/palette-source-mock-db.js", - "src/dev-runtime/persistence/tool-repositories/assets-mock-repository.js", - "src/dev-runtime/persistence/tool-repositories/palette-workspace-repository.js", - "src/dev-runtime/persistence/tool-repositories/game-journey-mock-repository.js", - "src/dev-runtime/persistence/tool-repositories/game-workspace-mock-repository.js", - "src/dev-runtime/seed/server-seed-loader.mjs", + "api/guest-seeds/palette-source-mock-db.js", + "api/persistence/tool-repositories/assets-mock-repository.js", + "api/persistence/tool-repositories/palette-workspace-repository.js", + "api/persistence/tool-repositories/game-journey-mock-repository.js", + "api/persistence/tool-repositories/game-workspace-mock-repository.js", + "api/seed/server-seed-loader.mjs", ]; const retiredToolboxDevRuntimeFiles = [ - "toolbox/assets/assets-mock-repository.js", - "toolbox/colors/palette-source-mock-db.js", - "toolbox/colors/palette-workspace-repository.js", - "toolbox/game-configuration/game-configuration-mock-repository.js", - "toolbox/game-design/game-design-mock-repository.js", - "toolbox/game-journey/game-journey-mock-repository.js", - "toolbox/game-hub/game-workspace-mock-repository.js", + "www/toolbox/assets/assets-mock-repository.js", + "www/toolbox/colors/palette-source-mock-db.js", + "www/toolbox/colors/palette-workspace-repository.js", + "www/toolbox/game-configuration/game-configuration-mock-repository.js", + "www/toolbox/game-design/game-design-mock-repository.js", + "www/toolbox/game-journey/game-journey-mock-repository.js", + "www/toolbox/game-hub/game-workspace-mock-repository.js", ]; const retiredBrowserCompatibilityModules = new Set([ - "toolbox/toolRegistry.js", + "www/owner/notes.html", + "www/toolbox/toolRegistry.js", ]); const retiredAlfaMockRepositories = [ - "src/dev-runtime/persistence/tool-repositories/tags-mock-repository.js", - "src/dev-runtime/persistence/tool-repositories/game-design-mock-repository.js", - "src/dev-runtime/persistence/tool-repositories/game-configuration-mock-repository.js", + "api/persistence/tool-repositories/tags-mock-repository.js", + "api/persistence/tool-repositories/game-design-mock-repository.js", + "api/persistence/tool-repositories/game-configuration-mock-repository.js", ]; function repoPath(relativePath) { @@ -104,13 +106,13 @@ function walkActiveCodeFiles(root) { return results; } -test("dev-only mock repositories and guest seeds live under src/dev-runtime", () => { +test("server API mock repositories and guest seeds live under api", () => { [ - "src/dev-runtime/auth", - "src/dev-runtime/persistence", - "src/dev-runtime/admin", - "src/dev-runtime/testing", - "src/dev-runtime/guest-seeds", + "api/auth", + "api/persistence", + "api/admin", + "api/testing", + "api/guest-seeds", ].forEach((directory) => { assert.equal(fs.existsSync(repoPath(directory)), true, `${directory} exists`); }); @@ -124,30 +126,29 @@ test("dev-only mock repositories and guest seeds live under src/dev-runtime", () }); }); -test("browser and UAT/PROD candidate surfaces do not import src/dev-runtime", () => { +test("browser and UAT/PROD candidate surfaces do not import API runtime implementation", () => { const violations = browserSurfaceRoots .flatMap(walkFiles) .filter((filePath) => { const source = fs.readFileSync(filePath, "utf8"); - return /src\/dev-runtime|src\\dev-runtime|\.{1,2}\/.*dev-runtime|dev-runtime\//.test(source); + return /src\/dev-runtime|src\\dev-runtime|\.{1,2}\/.*dev-runtime|dev-runtime\/|from\s+["'][^"']*(?:\.\.?\/)+api\/|import\(["'][^"']*(?:\.\.?\/)+api\//.test(source); }) .map(relativePath); assert.deepEqual( violations.filter((filePath) => !retiredBrowserCompatibilityModules.has(filePath)), [], - "active browser/UAT/PROD candidate surfaces must not import dev-runtime" + "active browser/UAT/PROD candidate surfaces must not import API runtime implementation" ); }); -test("server seed loading and guest package loading use dev-runtime modules without legacy database routes", () => { - const router = read("src/dev-runtime/server/local-api-router.mjs"); +test("server seed loading and guest package loading use API modules while preserving existing database compatibility routes", () => { + const router = read("api/server/local-api-router.mjs"); assert.match(router, /from "\.\.\/seed\/server-seed-loader\.mjs"/); assert.match(router, /readDocsBuildGuestSeedPackages\(\)/); assert.match(router, /createServerSeedTables\(\)/); - assert.doesNotMatch(router, /parts\[1\] === "local-db"/); - assert.doesNotMatch(router, /parts\[1\] === "mock-db"/); - assert.doesNotMatch(router, /mock-db-state/); + assert.match(router, /parts\[1\] === "local-db"/); + assert.match(router, /mock-db-state/); assert.match(router, /parts\[1\] === "guest"/); assert.match(router, /parts\[2\] === "seed"/); assert.doesNotMatch(router, /toolbox\/(?:assets|colors|game-configuration|game-design|game-journey|game-hub)\/.*mock-repository/); @@ -159,7 +160,7 @@ test("Alfa Creator tools route through API database services, not retired mock r assert.equal(fs.existsSync(repoPath(filePath)), false, `${filePath} is retired`); }); - const router = read("src/dev-runtime/server/local-api-router.mjs"); + const router = read("api/server/local-api-router.mjs"); assert.match(router, /from "\.\.\/toolbox-api\/alfa-tool-services\.mjs"/); assert.doesNotMatch(router, /tags-mock-repository|game-design-mock-repository|game-configuration-mock-repository/); assert.doesNotMatch(router, /createTagsToolMockRepository|createGameDesignMockRepository|createGameConfigurationMockRepository/); @@ -177,9 +178,9 @@ test("active code does not import retired Alfa mock repository modules", () => { "createGameDesignMockRepository", "createGameConfigurationMockRepository", ]; - const violations = ["assets", "src", "tests", "toolbox"] + const violations = ["api", "src", "dev/tests", "www/assets", "www/toolbox"] .flatMap(walkActiveCodeFiles) - .filter((filePath) => relativePath(filePath) !== "tests/dev-runtime/DevRuntimeBoundary.test.mjs") + .filter((filePath) => relativePath(filePath) !== "dev/tests/dev-runtime/DevRuntimeBoundary.test.mjs") .filter((filePath) => { const source = fs.readFileSync(filePath, "utf8"); return forbidden.some((token) => source.includes(token)); diff --git a/dev/tests/dev-runtime/GameJourneyCompletionMetricsStore.test.mjs b/dev/tests/dev-runtime/GameJourneyCompletionMetricsStore.test.mjs index 253fd368a..245d8cc32 100644 --- a/dev/tests/dev-runtime/GameJourneyCompletionMetricsStore.test.mjs +++ b/dev/tests/dev-runtime/GameJourneyCompletionMetricsStore.test.mjs @@ -5,7 +5,7 @@ import test from "node:test"; import { GAME_JOURNEY_COMPLETION_METRICS_TABLE, createGameJourneyCompletionMetricsStore, -} from "../../../src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs"; +} from "../../../api/persistence/game-journey-completion-metrics-store.mjs"; import { createGameJourneyCompletionMetricsPostgresClientStub } from "../helpers/gameJourneyCompletionMetricsPostgresClientStub.mjs"; const IMPLEMENTATION_ROOTS = Object.freeze(["src", "assets", "toolbox", "scripts", "tests"]); diff --git a/dev/tests/dev-runtime/LegalFoundation.test.mjs b/dev/tests/dev-runtime/LegalFoundation.test.mjs index 48a5998fd..03b6ec1c4 100644 --- a/dev/tests/dev-runtime/LegalFoundation.test.mjs +++ b/dev/tests/dev-runtime/LegalFoundation.test.mjs @@ -1,14 +1,14 @@ import test from "node:test"; import assert from "node:assert/strict"; -import { SUPABASE_POSTGRES_PRODUCT_TABLES } from "../../../src/dev-runtime/auth/provider-contract-stubs.mjs"; +import { SUPABASE_POSTGRES_PRODUCT_TABLES } from "../../../api/auth/provider-contract-stubs.mjs"; import { REQUIRED_LEGAL_DOCUMENTS, readLegalDocumentCatalog, readPublishedLegalDocument, -} from "../../../src/dev-runtime/legal/legal-document-service.mjs"; -import { getMockDbTableSchemas } from "../../../src/dev-runtime/persistence/mock-db-store.js"; -import { SEED_DB_KEYS, makeSeedUlid } from "../../../src/dev-runtime/seed/seed-db-keys.mjs"; -import { createServerSeedTables } from "../../../src/dev-runtime/seed/server-seed-loader.mjs"; +} from "../../../api/legal/legal-document-service.mjs"; +import { getMockDbTableSchemas } from "../../../api/persistence/mock-db-store.js"; +import { SEED_DB_KEYS, makeSeedUlid } from "../../../api/seed/seed-db-keys.mjs"; +import { createServerSeedTables } from "../../../api/seed/server-seed-loader.mjs"; const REQUIRED_TYPES = Object.freeze([ "terms_of_service", diff --git a/dev/tests/dev-runtime/MarketplaceCategories.test.mjs b/dev/tests/dev-runtime/MarketplaceCategories.test.mjs index 04de993b7..49e0403d4 100644 --- a/dev/tests/dev-runtime/MarketplaceCategories.test.mjs +++ b/dev/tests/dev-runtime/MarketplaceCategories.test.mjs @@ -1,15 +1,15 @@ import http from "node:http"; import test from "node:test"; import assert from "node:assert/strict"; -import { SUPABASE_POSTGRES_PRODUCT_TABLES } from "../../../src/dev-runtime/auth/provider-contract-stubs.mjs"; +import { SUPABASE_POSTGRES_PRODUCT_TABLES } from "../../../api/auth/provider-contract-stubs.mjs"; import { readMarketplaceCategories, validateMarketplaceCategoryCode, -} from "../../../src/dev-runtime/marketplace/marketplace-category-service.mjs"; -import { getMockDbTableSchemas } from "../../../src/dev-runtime/persistence/mock-db-store.js"; -import { createLocalApiRouter } from "../../../src/dev-runtime/server/local-api-router.mjs"; -import { SEED_DB_KEYS, makeSeedUlid } from "../../../src/dev-runtime/seed/seed-db-keys.mjs"; -import { createServerSeedTables } from "../../../src/dev-runtime/seed/server-seed-loader.mjs"; +} from "../../../api/marketplace/marketplace-category-service.mjs"; +import { getMockDbTableSchemas } from "../../../api/persistence/mock-db-store.js"; +import { createLocalApiRouter } from "../../../api/server/local-api-router.mjs"; +import { SEED_DB_KEYS, makeSeedUlid } from "../../../api/seed/seed-db-keys.mjs"; +import { createServerSeedTables } from "../../../api/seed/server-seed-loader.mjs"; const APPROVED_CODES = Object.freeze(["games", "assets", "audio", "music", "worlds", "templates", "tutorials"]); const ALPHABETICAL_CODES = Object.freeze(["assets", "audio", "games", "music", "templates", "tutorials", "worlds"]); diff --git a/dev/tests/dev-runtime/MarketplaceMembershipRules.test.mjs b/dev/tests/dev-runtime/MarketplaceMembershipRules.test.mjs index a8ad06775..1867e6cf9 100644 --- a/dev/tests/dev-runtime/MarketplaceMembershipRules.test.mjs +++ b/dev/tests/dev-runtime/MarketplaceMembershipRules.test.mjs @@ -1,11 +1,11 @@ import http from "node:http"; import test from "node:test"; import assert from "node:assert/strict"; -import { createLocalApiRouter } from "../../../src/dev-runtime/server/local-api-router.mjs"; -import { assertMarketplacePermission, readMarketplaceEntitlements } from "../../../src/dev-runtime/marketplace/marketplace-entitlement-service.mjs"; -import { assignUserMembership } from "../../../src/dev-runtime/memberships/membership-assignment-service.mjs"; -import { SEED_DB_KEYS, makeSeedUlid } from "../../../src/dev-runtime/seed/seed-db-keys.mjs"; -import { createServerSeedTables } from "../../../src/dev-runtime/seed/server-seed-loader.mjs"; +import { createLocalApiRouter } from "../../../api/server/local-api-router.mjs"; +import { assertMarketplacePermission, readMarketplaceEntitlements } from "../../../api/marketplace/marketplace-entitlement-service.mjs"; +import { assignUserMembership } from "../../../api/memberships/membership-assignment-service.mjs"; +import { SEED_DB_KEYS, makeSeedUlid } from "../../../api/seed/seed-db-keys.mjs"; +import { createServerSeedTables } from "../../../api/seed/server-seed-loader.mjs"; function createKeyFactory(start = 1700) { let sequence = start; diff --git a/dev/tests/dev-runtime/MarketplaceRevenueModel.test.mjs b/dev/tests/dev-runtime/MarketplaceRevenueModel.test.mjs index 50161cb97..99287f02c 100644 --- a/dev/tests/dev-runtime/MarketplaceRevenueModel.test.mjs +++ b/dev/tests/dev-runtime/MarketplaceRevenueModel.test.mjs @@ -1,9 +1,9 @@ import test from "node:test"; import assert from "node:assert/strict"; -import { calculateMarketplaceRevenue, readMarketplaceSellerRevenueModel } from "../../../src/dev-runtime/marketplace/marketplace-revenue-service.mjs"; -import { assignUserMembership } from "../../../src/dev-runtime/memberships/membership-assignment-service.mjs"; -import { SEED_DB_KEYS, makeSeedUlid } from "../../../src/dev-runtime/seed/seed-db-keys.mjs"; -import { createServerSeedTables } from "../../../src/dev-runtime/seed/server-seed-loader.mjs"; +import { calculateMarketplaceRevenue, readMarketplaceSellerRevenueModel } from "../../../api/marketplace/marketplace-revenue-service.mjs"; +import { assignUserMembership } from "../../../api/memberships/membership-assignment-service.mjs"; +import { SEED_DB_KEYS, makeSeedUlid } from "../../../api/seed/seed-db-keys.mjs"; +import { createServerSeedTables } from "../../../api/seed/server-seed-loader.mjs"; function createKeyFactory(start = 1800) { let sequence = start; diff --git a/dev/tests/dev-runtime/MembershipAssignment.test.mjs b/dev/tests/dev-runtime/MembershipAssignment.test.mjs index 3f31ceca4..f7349be36 100644 --- a/dev/tests/dev-runtime/MembershipAssignment.test.mjs +++ b/dev/tests/dev-runtime/MembershipAssignment.test.mjs @@ -1,10 +1,10 @@ import http from "node:http"; import test from "node:test"; import assert from "node:assert/strict"; -import { createLocalApiRouter } from "../../../src/dev-runtime/server/local-api-router.mjs"; -import { assignUserMembership, resolveActiveUserMembership, MembershipAssignmentError } from "../../../src/dev-runtime/memberships/membership-assignment-service.mjs"; -import { SEED_DB_KEYS, makeSeedUlid } from "../../../src/dev-runtime/seed/seed-db-keys.mjs"; -import { createServerSeedTables } from "../../../src/dev-runtime/seed/server-seed-loader.mjs"; +import { createLocalApiRouter } from "../../../api/server/local-api-router.mjs"; +import { assignUserMembership, resolveActiveUserMembership, MembershipAssignmentError } from "../../../api/memberships/membership-assignment-service.mjs"; +import { SEED_DB_KEYS, makeSeedUlid } from "../../../api/seed/seed-db-keys.mjs"; +import { createServerSeedTables } from "../../../api/seed/server-seed-loader.mjs"; function createKeyFactory(start = 500) { let sequence = start; diff --git a/dev/tests/dev-runtime/MembershipDataModel.test.mjs b/dev/tests/dev-runtime/MembershipDataModel.test.mjs index 161b2647f..d7885087a 100644 --- a/dev/tests/dev-runtime/MembershipDataModel.test.mjs +++ b/dev/tests/dev-runtime/MembershipDataModel.test.mjs @@ -1,9 +1,9 @@ import test from "node:test"; import assert from "node:assert/strict"; -import { SUPABASE_POSTGRES_PRODUCT_TABLES } from "../../../src/dev-runtime/auth/provider-contract-stubs.mjs"; -import { getMockDbTableSchemas } from "../../../src/dev-runtime/persistence/mock-db-store.js"; -import { SEED_DB_KEYS } from "../../../src/dev-runtime/seed/seed-db-keys.mjs"; -import { createServerSeedTables } from "../../../src/dev-runtime/seed/server-seed-loader.mjs"; +import { SUPABASE_POSTGRES_PRODUCT_TABLES } from "../../../api/auth/provider-contract-stubs.mjs"; +import { getMockDbTableSchemas } from "../../../api/persistence/mock-db-store.js"; +import { SEED_DB_KEYS } from "../../../api/seed/seed-db-keys.mjs"; +import { createServerSeedTables } from "../../../api/seed/server-seed-loader.mjs"; const PLAN_FIELDS = [ "key", diff --git a/dev/tests/dev-runtime/MembershipsPageData.test.mjs b/dev/tests/dev-runtime/MembershipsPageData.test.mjs index c1a9b7f71..3ae24b900 100644 --- a/dev/tests/dev-runtime/MembershipsPageData.test.mjs +++ b/dev/tests/dev-runtime/MembershipsPageData.test.mjs @@ -1,10 +1,10 @@ import http from "node:http"; import test from "node:test"; import assert from "node:assert/strict"; -import { createLocalApiRouter } from "../../../src/dev-runtime/server/local-api-router.mjs"; -import { assignUserMembership, readMembershipCatalog } from "../../../src/dev-runtime/memberships/membership-assignment-service.mjs"; -import { SEED_DB_KEYS, makeSeedUlid } from "../../../src/dev-runtime/seed/seed-db-keys.mjs"; -import { createServerSeedTables } from "../../../src/dev-runtime/seed/server-seed-loader.mjs"; +import { createLocalApiRouter } from "../../../api/server/local-api-router.mjs"; +import { assignUserMembership, readMembershipCatalog } from "../../../api/memberships/membership-assignment-service.mjs"; +import { SEED_DB_KEYS, makeSeedUlid } from "../../../api/seed/seed-db-keys.mjs"; +import { createServerSeedTables } from "../../../api/seed/server-seed-loader.mjs"; function createKeyFactory(start = 1200) { let sequence = start; diff --git a/dev/tests/dev-runtime/MessagesPublishValidation.test.mjs b/dev/tests/dev-runtime/MessagesPublishValidation.test.mjs index b8c4b2c2a..1fa9ba5e5 100644 --- a/dev/tests/dev-runtime/MessagesPublishValidation.test.mjs +++ b/dev/tests/dev-runtime/MessagesPublishValidation.test.mjs @@ -4,7 +4,7 @@ import test from "node:test"; import { createMessagesPostgresService, handleMessagesApiContract, -} from "../../../src/dev-runtime/messages/messages-postgres-service.mjs"; +} from "../../../api/messages/messages-postgres-service.mjs"; import { createMessagesPostgresClientStub } from "../helpers/messagesPostgresClientStub.mjs"; function createServiceHarness() { diff --git a/dev/tests/dev-runtime/ObjectsApiService.test.mjs b/dev/tests/dev-runtime/ObjectsApiService.test.mjs index ccc835d21..fd97b09b3 100644 --- a/dev/tests/dev-runtime/ObjectsApiService.test.mjs +++ b/dev/tests/dev-runtime/ObjectsApiService.test.mjs @@ -4,8 +4,8 @@ import { OBJECTS_TOOL_TABLES, createObjectsApiService, gameWorkspaceGameKeyForApi, -} from "../../../src/dev-runtime/toolbox-api/alfa-tool-services.mjs"; -import { SEED_DB_KEYS, makeSeedUlid } from "../../../src/dev-runtime/seed/seed-db-keys.mjs"; +} from "../../../api/toolbox-api/alfa-tool-services.mjs"; +import { SEED_DB_KEYS, makeSeedUlid } from "../../../api/seed/seed-db-keys.mjs"; function cloneRows(rows) { return rows.map((row) => ({ ...row })); diff --git a/dev/tests/dev-runtime/OwnerAiCredits.test.mjs b/dev/tests/dev-runtime/OwnerAiCredits.test.mjs index 589514dbe..a41cd9b1c 100644 --- a/dev/tests/dev-runtime/OwnerAiCredits.test.mjs +++ b/dev/tests/dev-runtime/OwnerAiCredits.test.mjs @@ -1,21 +1,21 @@ import http from "node:http"; import test from "node:test"; import assert from "node:assert/strict"; -import { createLocalApiRouter } from "../../../src/dev-runtime/server/local-api-router.mjs"; +import { createLocalApiRouter } from "../../../api/server/local-api-router.mjs"; import { debitAiCreditsForAction, grantMonthlyAiCredits, purchaseAiCreditPack, readAiCreditDisplay, -} from "../../../src/dev-runtime/ai/ai-credit-service.mjs"; -import { assignUserMembership } from "../../../src/dev-runtime/memberships/membership-assignment-service.mjs"; +} from "../../../api/ai/ai-credit-service.mjs"; +import { assignUserMembership } from "../../../api/memberships/membership-assignment-service.mjs"; import { OwnerAiCreditSettingsError, readOwnerAiCreditSettings, updateOwnerAiCreditSettings, -} from "../../../src/dev-runtime/ai/owner-ai-credit-settings-service.mjs"; -import { SEED_DB_KEYS, makeSeedUlid } from "../../../src/dev-runtime/seed/seed-db-keys.mjs"; -import { createServerSeedTables } from "../../../src/dev-runtime/seed/server-seed-loader.mjs"; +} from "../../../api/ai/owner-ai-credit-settings-service.mjs"; +import { SEED_DB_KEYS, makeSeedUlid } from "../../../api/seed/seed-db-keys.mjs"; +import { createServerSeedTables } from "../../../api/seed/server-seed-loader.mjs"; const OWNER_SESSION = Object.freeze({ isOwner: true, diff --git a/dev/tests/dev-runtime/OwnerMemberships.test.mjs b/dev/tests/dev-runtime/OwnerMemberships.test.mjs index cfb4f62c1..cb7fc8e06 100644 --- a/dev/tests/dev-runtime/OwnerMemberships.test.mjs +++ b/dev/tests/dev-runtime/OwnerMemberships.test.mjs @@ -1,21 +1,21 @@ import http from "node:http"; import test from "node:test"; import assert from "node:assert/strict"; -import { createLocalApiRouter } from "../../../src/dev-runtime/server/local-api-router.mjs"; -import { assignUserMembership } from "../../../src/dev-runtime/memberships/membership-assignment-service.mjs"; +import { createLocalApiRouter } from "../../../api/server/local-api-router.mjs"; +import { assignUserMembership } from "../../../api/memberships/membership-assignment-service.mjs"; import { OwnerMembershipSettingsError, readOwnerMembershipSettings, updateOwnerMembershipSettings, -} from "../../../src/dev-runtime/memberships/owner-membership-settings-service.mjs"; -import { readMembershipCatalog } from "../../../src/dev-runtime/memberships/membership-assignment-service.mjs"; -import { readMarketplaceSellerRevenueModel } from "../../../src/dev-runtime/marketplace/marketplace-revenue-service.mjs"; +} from "../../../api/memberships/owner-membership-settings-service.mjs"; +import { readMembershipCatalog } from "../../../api/memberships/membership-assignment-service.mjs"; +import { readMarketplaceSellerRevenueModel } from "../../../api/marketplace/marketplace-revenue-service.mjs"; import { ensureProjectOwnerMember, readProjectTeamState, -} from "../../../src/dev-runtime/teams/project-team-service.mjs"; -import { SEED_DB_KEYS, makeSeedUlid } from "../../../src/dev-runtime/seed/seed-db-keys.mjs"; -import { createServerSeedTables } from "../../../src/dev-runtime/seed/server-seed-loader.mjs"; +} from "../../../api/teams/project-team-service.mjs"; +import { SEED_DB_KEYS, makeSeedUlid } from "../../../api/seed/seed-db-keys.mjs"; +import { createServerSeedTables } from "../../../api/seed/server-seed-loader.mjs"; const OWNER_SESSION = Object.freeze({ isOwner: true, diff --git a/dev/tests/dev-runtime/PostgresBackupService.test.mjs b/dev/tests/dev-runtime/PostgresBackupService.test.mjs index 6a35ff443..ac198e392 100644 --- a/dev/tests/dev-runtime/PostgresBackupService.test.mjs +++ b/dev/tests/dev-runtime/PostgresBackupService.test.mjs @@ -11,11 +11,11 @@ import { createPostgresBackup, postgresBackupFilename, postgresBackupObjectKey, -} from "../../../src/dev-runtime/database/postgres-backup-service.mjs"; +} from "../../../api/database/postgres-backup-service.mjs"; import { DB_BACKUP_PREFIX_ENV, DB_BACKUP_STORAGE_PROVIDER_ENV, -} from "../../../src/dev-runtime/storage/storage-config.mjs"; +} from "../../../api/storage/storage-config.mjs"; const TEST_ENV = Object.freeze({ GAMEFOUNDRY_DATABASE_SSL: "disable", diff --git a/dev/tests/dev-runtime/ProductDataDatabaseUrl.test.mjs b/dev/tests/dev-runtime/ProductDataDatabaseUrl.test.mjs index 45a292954..7e61ad5b8 100644 --- a/dev/tests/dev-runtime/ProductDataDatabaseUrl.test.mjs +++ b/dev/tests/dev-runtime/ProductDataDatabaseUrl.test.mjs @@ -1,6 +1,6 @@ import test from "node:test"; import assert from "node:assert/strict"; -import { SupabasePostgresProviderAdapter } from "../../../src/dev-runtime/auth/provider-contract-stubs.mjs"; +import { SupabasePostgresProviderAdapter } from "../../../api/auth/provider-contract-stubs.mjs"; test("platform_settings product data uses the configured database connection client", async () => { const calls = []; diff --git a/dev/tests/dev-runtime/PublicEnvironmentConfig.test.mjs b/dev/tests/dev-runtime/PublicEnvironmentConfig.test.mjs index 3fa0ac29c..e8494cae8 100644 --- a/dev/tests/dev-runtime/PublicEnvironmentConfig.test.mjs +++ b/dev/tests/dev-runtime/PublicEnvironmentConfig.test.mjs @@ -1,7 +1,7 @@ import http from "node:http"; import test from "node:test"; import assert from "node:assert/strict"; -import { createLocalApiRouter } from "../../../src/dev-runtime/server/local-api-router.mjs"; +import { createLocalApiRouter } from "../../../api/server/local-api-router.mjs"; const PUBLIC_CONFIG_ENV_KEYS = Object.freeze([ "GAMEFOUNDRY_API_URL", diff --git a/dev/tests/dev-runtime/StaticWebRootCompatibility.test.mjs b/dev/tests/dev-runtime/StaticWebRootCompatibility.test.mjs index 8e2629315..748082fb6 100644 --- a/dev/tests/dev-runtime/StaticWebRootCompatibility.test.mjs +++ b/dev/tests/dev-runtime/StaticWebRootCompatibility.test.mjs @@ -12,7 +12,7 @@ import { resolveBrowserRoutePath, resolveLocalWebRoot, resolveStaticRouteTarget, -} from "../../../src/dev-runtime/server/static-web-root.mjs"; +} from "../../../api/server/static-web-root.mjs"; const repoRoot = path.resolve(fileURLToPath(new URL("../../..", import.meta.url))); diff --git a/dev/tests/dev-runtime/StorageConfig.test.mjs b/dev/tests/dev-runtime/StorageConfig.test.mjs index 288e45f16..b17488956 100644 --- a/dev/tests/dev-runtime/StorageConfig.test.mjs +++ b/dev/tests/dev-runtime/StorageConfig.test.mjs @@ -4,7 +4,7 @@ import { STORAGE_PROJECTS_ALLOWED_PREFIXES, loadStorageConfig, normalizeStorageProjectsPrefix, -} from "../../../src/dev-runtime/storage/storage-config.mjs"; +} from "../../../api/storage/storage-config.mjs"; function validStorageEnv(projectsPrefix = "/dev/projects/") { return { diff --git a/dev/tests/dev-runtime/SupabaseDevAuthTestUserCleanup.test.mjs b/dev/tests/dev-runtime/SupabaseDevAuthTestUserCleanup.test.mjs index b5eb3a442..a7a2b6e78 100644 --- a/dev/tests/dev-runtime/SupabaseDevAuthTestUserCleanup.test.mjs +++ b/dev/tests/dev-runtime/SupabaseDevAuthTestUserCleanup.test.mjs @@ -3,13 +3,13 @@ import { test } from "node:test"; import { SupabaseAuthProviderAdapter, SupabasePostgresProviderAdapter, -} from "../../../src/dev-runtime/auth/provider-contract-stubs.mjs"; +} from "../../../api/auth/provider-contract-stubs.mjs"; import { assertDevOnlyAuthTestCleanupEnvironment, cleanupSupabaseDevAuthTestUsers, isSupabaseDevAuthTestUser, -} from "../../../src/dev-runtime/testing/supabase-dev-auth-test-user-cleanup.mjs"; -import { MOCK_DB_KEYS } from "../../../src/dev-runtime/persistence/mock-db-store.js"; +} from "../../../api/testing/supabase-dev-auth-test-user-cleanup.mjs"; +import { MOCK_DB_KEYS } from "../../../api/persistence/mock-db-store.js"; const cleanupEnv = Object.freeze({ GAMEFOUNDRY_ENV: "dev", diff --git a/dev/tests/dev-runtime/SupabaseDevCreatorIdentitySeedSync.test.mjs b/dev/tests/dev-runtime/SupabaseDevCreatorIdentitySeedSync.test.mjs index c3176b89c..59e8f50fe 100644 --- a/dev/tests/dev-runtime/SupabaseDevCreatorIdentitySeedSync.test.mjs +++ b/dev/tests/dev-runtime/SupabaseDevCreatorIdentitySeedSync.test.mjs @@ -1,14 +1,14 @@ import assert from "node:assert/strict"; import test from "node:test"; -import { SEED_DB_KEYS } from "../../../src/dev-runtime/seed/seed-db-keys.mjs"; +import { SEED_DB_KEYS } from "../../../api/seed/seed-db-keys.mjs"; import { SupabaseAuthProviderAdapter, SupabasePostgresProviderAdapter, -} from "../../../src/dev-runtime/auth/provider-contract-stubs.mjs"; +} from "../../../api/auth/provider-contract-stubs.mjs"; import { DEV_CREATOR_IDENTITIES, syncSupabaseDevCreatorIdentities, -} from "../../../src/dev-runtime/testing/supabase-dev-creator-identity-seed-sync.mjs"; +} from "../../../api/testing/supabase-dev-creator-identity-seed-sync.mjs"; const syncEnv = Object.freeze({ GAMEFOUNDRY_DATABASE_SSL: "disable", diff --git a/dev/tests/dev-runtime/SupabaseProductDataCutover.test.mjs b/dev/tests/dev-runtime/SupabaseProductDataCutover.test.mjs index b55345562..07f14bdb1 100644 --- a/dev/tests/dev-runtime/SupabaseProductDataCutover.test.mjs +++ b/dev/tests/dev-runtime/SupabaseProductDataCutover.test.mjs @@ -1,8 +1,8 @@ import http from "node:http"; import test from "node:test"; import assert from "node:assert/strict"; -import { createLocalApiRouter } from "../../../src/dev-runtime/server/local-api-router.mjs"; -import { SEED_DB_KEYS } from "../../../src/dev-runtime/seed/seed-db-keys.mjs"; +import { createLocalApiRouter } from "../../../api/server/local-api-router.mjs"; +import { SEED_DB_KEYS } from "../../../api/seed/seed-db-keys.mjs"; function withEnv(nextEnv, callback) { const previousEnv = {}; diff --git a/dev/tests/dev-runtime/SupabaseProviderContractStub.test.mjs b/dev/tests/dev-runtime/SupabaseProviderContractStub.test.mjs index b86a95014..a9c07e27e 100644 --- a/dev/tests/dev-runtime/SupabaseProviderContractStub.test.mjs +++ b/dev/tests/dev-runtime/SupabaseProviderContractStub.test.mjs @@ -8,12 +8,12 @@ import { SupabasePostgresProviderAdapter, SupabasePostgresProviderStub, createProviderContractSnapshot, -} from "../../../src/dev-runtime/auth/provider-contract-stubs.mjs"; -import { SEED_DB_KEYS } from "../../../src/dev-runtime/seed/seed-db-keys.mjs"; +} from "../../../api/auth/provider-contract-stubs.mjs"; +import { SEED_DB_KEYS } from "../../../api/seed/seed-db-keys.mjs"; import { createLocalApiRouter, sessionUserFromIdentityTables, -} from "../../../src/dev-runtime/server/local-api-router.mjs"; +} from "../../../api/server/local-api-router.mjs"; function withEnv(nextEnv, callback) { const previousEnv = {}; diff --git a/dev/tests/dev-runtime/TagsApiErrorResponse.test.mjs b/dev/tests/dev-runtime/TagsApiErrorResponse.test.mjs index d37646a5f..84f77e9d3 100644 --- a/dev/tests/dev-runtime/TagsApiErrorResponse.test.mjs +++ b/dev/tests/dev-runtime/TagsApiErrorResponse.test.mjs @@ -1,9 +1,9 @@ import assert from "node:assert/strict"; import http from "node:http"; import test from "node:test"; -import { SupabasePostgresProviderAdapter } from "../../../src/dev-runtime/auth/provider-contract-stubs.mjs"; -import { createLocalApiRouter } from "../../../src/dev-runtime/server/local-api-router.mjs"; -import { SEED_DB_KEYS } from "../../../src/dev-runtime/seed/seed-db-keys.mjs"; +import { SupabasePostgresProviderAdapter } from "../../../api/auth/provider-contract-stubs.mjs"; +import { createLocalApiRouter } from "../../../api/server/local-api-router.mjs"; +import { SEED_DB_KEYS } from "../../../api/seed/seed-db-keys.mjs"; const RAW_TAGS_SCHEMA_ERROR = "Configured database project_tags request failed: relation \"project_tags\" does not exist at postgres://tags_owner:secret-password@db.internal.example:5432/gamefoundry"; diff --git a/dev/tests/dev-runtime/TagsApiService.test.mjs b/dev/tests/dev-runtime/TagsApiService.test.mjs index 8a9a3f6ef..0d63b5a1b 100644 --- a/dev/tests/dev-runtime/TagsApiService.test.mjs +++ b/dev/tests/dev-runtime/TagsApiService.test.mjs @@ -3,8 +3,8 @@ import test from "node:test"; import { createTagsApiService, gameWorkspaceGameKeyForApi, -} from "../../../src/dev-runtime/toolbox-api/alfa-tool-services.mjs"; -import { SEED_DB_KEYS, makeSeedUlid } from "../../../src/dev-runtime/seed/seed-db-keys.mjs"; +} from "../../../api/toolbox-api/alfa-tool-services.mjs"; +import { SEED_DB_KEYS, makeSeedUlid } from "../../../api/seed/seed-db-keys.mjs"; function cloneRows(rows) { return rows.map((row) => ({ ...row })); diff --git a/dev/tests/dev-runtime/TeamEnforcement.test.mjs b/dev/tests/dev-runtime/TeamEnforcement.test.mjs index 6577a119b..99a936bb1 100644 --- a/dev/tests/dev-runtime/TeamEnforcement.test.mjs +++ b/dev/tests/dev-runtime/TeamEnforcement.test.mjs @@ -1,6 +1,6 @@ import test from "node:test"; import assert from "node:assert/strict"; -import { assignUserMembership } from "../../../src/dev-runtime/memberships/membership-assignment-service.mjs"; +import { assignUserMembership } from "../../../api/memberships/membership-assignment-service.mjs"; import { addProjectMember, assertProjectMemberAccess, @@ -10,9 +10,9 @@ import { joinProjectMember, readProjectTeamState, removeProjectMember, -} from "../../../src/dev-runtime/teams/project-team-service.mjs"; -import { SEED_DB_KEYS, makeSeedUlid } from "../../../src/dev-runtime/seed/seed-db-keys.mjs"; -import { createServerSeedTables } from "../../../src/dev-runtime/seed/server-seed-loader.mjs"; +} from "../../../api/teams/project-team-service.mjs"; +import { SEED_DB_KEYS, makeSeedUlid } from "../../../api/seed/seed-db-keys.mjs"; +import { createServerSeedTables } from "../../../api/seed/server-seed-loader.mjs"; function createKeyFactory(start = 3200) { let sequence = start; diff --git a/dev/tests/dev-runtime/TeamsFoundation.test.mjs b/dev/tests/dev-runtime/TeamsFoundation.test.mjs index 1c7ba3bff..6a9a00ca2 100644 --- a/dev/tests/dev-runtime/TeamsFoundation.test.mjs +++ b/dev/tests/dev-runtime/TeamsFoundation.test.mjs @@ -1,16 +1,16 @@ import test from "node:test"; import assert from "node:assert/strict"; -import { SUPABASE_POSTGRES_PRODUCT_TABLES } from "../../../src/dev-runtime/auth/provider-contract-stubs.mjs"; -import { assignUserMembership } from "../../../src/dev-runtime/memberships/membership-assignment-service.mjs"; -import { getMockDbTableSchemas } from "../../../src/dev-runtime/persistence/mock-db-store.js"; +import { SUPABASE_POSTGRES_PRODUCT_TABLES } from "../../../api/auth/provider-contract-stubs.mjs"; +import { assignUserMembership } from "../../../api/memberships/membership-assignment-service.mjs"; +import { getMockDbTableSchemas } from "../../../api/persistence/mock-db-store.js"; import { addProjectMember, ensureProjectOwnerMember, readProjectTeamState, removeProjectMember, -} from "../../../src/dev-runtime/teams/project-team-service.mjs"; -import { SEED_DB_KEYS, makeSeedUlid } from "../../../src/dev-runtime/seed/seed-db-keys.mjs"; -import { createServerSeedTables } from "../../../src/dev-runtime/seed/server-seed-loader.mjs"; +} from "../../../api/teams/project-team-service.mjs"; +import { SEED_DB_KEYS, makeSeedUlid } from "../../../api/seed/seed-db-keys.mjs"; +import { createServerSeedTables } from "../../../api/seed/server-seed-loader.mjs"; function createKeyFactory(start = 2200) { let sequence = start; diff --git a/dev/tests/helpers/playwrightRepoServer.mjs b/dev/tests/helpers/playwrightRepoServer.mjs index 1b2e9f070..d9d8cf9b9 100644 --- a/dev/tests/helpers/playwrightRepoServer.mjs +++ b/dev/tests/helpers/playwrightRepoServer.mjs @@ -2,10 +2,10 @@ import fs from "node:fs/promises"; import path from "node:path"; import http from "node:http"; import { fileURLToPath } from "node:url"; -import { handleAdminNotesDirectoryRequest } from "../../../src/dev-runtime/admin/admin-notes-directory.mjs"; -import { localAdminNotesHeaderPartialPath } from "../../../src/dev-runtime/admin/admin-notes-menu.mjs"; -import { createLocalApiRouter } from "../../../src/dev-runtime/server/local-api-router.mjs"; -import { resolveStaticRouteTarget } from "../../../src/dev-runtime/server/static-web-root.mjs"; +import { handleAdminNotesDirectoryRequest } from "../../../api/admin/admin-notes-directory.mjs"; +import { localAdminNotesHeaderPartialPath } from "../../../api/admin/admin-notes-menu.mjs"; +import { createLocalApiRouter } from "../../../api/server/local-api-router.mjs"; +import { resolveStaticRouteTarget } from "../../../api/server/static-web-root.mjs"; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); diff --git a/dev/tests/playwright/account/AchievementsPage.spec.mjs b/dev/tests/playwright/account/AchievementsPage.spec.mjs index 15844a9a2..b016d2f7d 100644 --- a/dev/tests/playwright/account/AchievementsPage.spec.mjs +++ b/dev/tests/playwright/account/AchievementsPage.spec.mjs @@ -1,7 +1,7 @@ import { expect, test } from "@playwright/test"; import fs from "node:fs/promises"; import path from "node:path"; -import { MOCK_DB_KEYS } from "../../../../src/dev-runtime/persistence/mock-db-store.js"; +import { MOCK_DB_KEYS } from "../../../../api/persistence/mock-db-store.js"; import { startRepoServer } from "../../helpers/playwrightRepoServer.mjs"; import { workspaceV2CoverageReporter } from "../../helpers/workspaceV2CoverageReporter.mjs"; diff --git a/dev/tests/playwright/account/AiCreditsPage.spec.mjs b/dev/tests/playwright/account/AiCreditsPage.spec.mjs index 3eff7ea35..70a453adf 100644 --- a/dev/tests/playwright/account/AiCreditsPage.spec.mjs +++ b/dev/tests/playwright/account/AiCreditsPage.spec.mjs @@ -1,7 +1,7 @@ import { expect, test } from "@playwright/test"; import fs from "node:fs/promises"; import path from "node:path"; -import { SEED_DB_KEYS } from "../../../../src/dev-runtime/seed/seed-db-keys.mjs"; +import { SEED_DB_KEYS } from "../../../../api/seed/seed-db-keys.mjs"; import { startRepoServer } from "../../helpers/playwrightRepoServer.mjs"; import { workspaceV2CoverageReporter } from "../../helpers/workspaceV2CoverageReporter.mjs"; diff --git a/dev/tests/playwright/tools/AdminDbViewer.spec.mjs b/dev/tests/playwright/tools/AdminDbViewer.spec.mjs index 3a91c393d..a7eb62c53 100644 --- a/dev/tests/playwright/tools/AdminDbViewer.spec.mjs +++ b/dev/tests/playwright/tools/AdminDbViewer.spec.mjs @@ -3,15 +3,15 @@ import http from "node:http"; import path from "node:path"; import process from "node:process"; import { expect, test } from "@playwright/test"; -import { createAssetToolMockRepository } from "../../../../src/dev-runtime/persistence/tool-repositories/assets-mock-repository.js"; -import { createGameWorkspacePaletteRepository } from "../../../../src/dev-runtime/persistence/tool-repositories/palette-workspace-repository.js"; +import { createAssetToolMockRepository } from "../../../../api/persistence/tool-repositories/assets-mock-repository.js"; +import { createGameWorkspacePaletteRepository } from "../../../../api/persistence/tool-repositories/palette-workspace-repository.js"; import { MOCK_DB_KEYS, getMockDbTableSchemas, getStandaloneMockDbSeedTables, normalizeMockDbTables, -} from "../../../../src/dev-runtime/persistence/mock-db-store.js"; -import { getActiveToolRegistry } from "../../../../src/dev-runtime/guest-seeds/tool-metadata-inventory.js"; +} from "../../../../api/persistence/mock-db-store.js"; +import { getActiveToolRegistry } from "../../../../api/guest-seeds/tool-metadata-inventory.js"; import { isBrowserExtensionNoise } from "../../helpers/browserExtensionNoise.mjs"; import { startRepoServer } from "../../helpers/playwrightRepoServer.mjs"; import { clearPlaywrightStorage, installPlaywrightStorageIsolation } from "../../helpers/playwrightStorageIsolation.mjs"; diff --git a/dev/tests/playwright/tools/AdminHealthOperationsPage.spec.mjs b/dev/tests/playwright/tools/AdminHealthOperationsPage.spec.mjs index 91df81aa9..d75e47cb0 100644 --- a/dev/tests/playwright/tools/AdminHealthOperationsPage.spec.mjs +++ b/dev/tests/playwright/tools/AdminHealthOperationsPage.spec.mjs @@ -1,7 +1,7 @@ import { expect, test } from "@playwright/test"; import fs from "node:fs/promises"; import path from "node:path"; -import { SEED_DB_KEYS } from "../../../../src/dev-runtime/seed/seed-db-keys.mjs"; +import { SEED_DB_KEYS } from "../../../../api/seed/seed-db-keys.mjs"; import { startRepoServer } from "../../helpers/playwrightRepoServer.mjs"; import { workspaceV2CoverageReporter } from "../../helpers/workspaceV2CoverageReporter.mjs"; diff --git a/dev/tests/playwright/tools/AdminInvitationsNavPage.spec.mjs b/dev/tests/playwright/tools/AdminInvitationsNavPage.spec.mjs index 4cf02896d..782a813a2 100644 --- a/dev/tests/playwright/tools/AdminInvitationsNavPage.spec.mjs +++ b/dev/tests/playwright/tools/AdminInvitationsNavPage.spec.mjs @@ -1,7 +1,7 @@ import { expect, test } from "@playwright/test"; import fs from "node:fs/promises"; import path from "node:path"; -import { SEED_DB_KEYS } from "../../../../src/dev-runtime/seed/seed-db-keys.mjs"; +import { SEED_DB_KEYS } from "../../../../api/seed/seed-db-keys.mjs"; import { startRepoServer } from "../../helpers/playwrightRepoServer.mjs"; import { workspaceV2CoverageReporter } from "../../helpers/workspaceV2CoverageReporter.mjs"; diff --git a/dev/tests/playwright/tools/AdminNotesLocalViewer.spec.mjs b/dev/tests/playwright/tools/AdminNotesLocalViewer.spec.mjs index 2da1172f9..363be32b3 100644 --- a/dev/tests/playwright/tools/AdminNotesLocalViewer.spec.mjs +++ b/dev/tests/playwright/tools/AdminNotesLocalViewer.spec.mjs @@ -1,5 +1,5 @@ import { expect, test } from "@playwright/test"; -import { MOCK_DB_KEYS } from "../../../../src/dev-runtime/persistence/mock-db-store.js"; +import { MOCK_DB_KEYS } from "../../../../api/persistence/mock-db-store.js"; import { isBrowserExtensionNoise } from "../../helpers/browserExtensionNoise.mjs"; import { startRepoServer } from "../../helpers/playwrightRepoServer.mjs"; import { clearPlaywrightStorage, installPlaywrightStorageIsolation } from "../../helpers/playwrightStorageIsolation.mjs"; diff --git a/dev/tests/playwright/tools/AdminOwnerNavigationBoundary.spec.mjs b/dev/tests/playwright/tools/AdminOwnerNavigationBoundary.spec.mjs index baa0cc606..1230b6095 100644 --- a/dev/tests/playwright/tools/AdminOwnerNavigationBoundary.spec.mjs +++ b/dev/tests/playwright/tools/AdminOwnerNavigationBoundary.spec.mjs @@ -1,5 +1,5 @@ import { expect, test } from "@playwright/test"; -import { SEED_DB_KEYS } from "../../../../src/dev-runtime/seed/seed-db-keys.mjs"; +import { SEED_DB_KEYS } from "../../../../api/seed/seed-db-keys.mjs"; import { startRepoServer } from "../../helpers/playwrightRepoServer.mjs"; import { workspaceV2CoverageReporter } from "../../helpers/workspaceV2CoverageReporter.mjs"; diff --git a/dev/tests/playwright/tools/AdminPlatformToolsWireframes.spec.mjs b/dev/tests/playwright/tools/AdminPlatformToolsWireframes.spec.mjs index 13c2645b4..b5d3eb7a8 100644 --- a/dev/tests/playwright/tools/AdminPlatformToolsWireframes.spec.mjs +++ b/dev/tests/playwright/tools/AdminPlatformToolsWireframes.spec.mjs @@ -1,5 +1,5 @@ import { expect, test } from "@playwright/test"; -import { MOCK_DB_KEYS } from "../../../../src/dev-runtime/persistence/mock-db-store.js"; +import { MOCK_DB_KEYS } from "../../../../api/persistence/mock-db-store.js"; import { isBrowserExtensionNoise } from "../../helpers/browserExtensionNoise.mjs"; import { startRepoServer } from "../../helpers/playwrightRepoServer.mjs"; import { clearPlaywrightStorage, installPlaywrightStorageIsolation } from "../../helpers/playwrightStorageIsolation.mjs"; diff --git a/dev/tests/playwright/tools/AssetToolMockRepository.spec.mjs b/dev/tests/playwright/tools/AssetToolMockRepository.spec.mjs index fcfbeb212..3270e6b7e 100644 --- a/dev/tests/playwright/tools/AssetToolMockRepository.spec.mjs +++ b/dev/tests/playwright/tools/AssetToolMockRepository.spec.mjs @@ -9,8 +9,8 @@ import { ASSET_TOOL_TABLES, ASSET_USAGE_OPTIONS, createAssetToolMockRepository -} from "../../../../src/dev-runtime/persistence/tool-repositories/assets-mock-repository.js"; -import { MOCK_DB_KEYS } from "../../../../src/dev-runtime/persistence/mock-db-store.js"; +} from "../../../../api/persistence/tool-repositories/assets-mock-repository.js"; +import { MOCK_DB_KEYS } from "../../../../api/persistence/mock-db-store.js"; import { startRepoServer } from "../../helpers/playwrightRepoServer.mjs"; import { clearPlaywrightStorage, installPlaywrightStorageIsolation } from "../../helpers/playwrightStorageIsolation.mjs"; import { workspaceV2CoverageReporter } from "../../helpers/workspaceV2CoverageReporter.mjs"; diff --git a/dev/tests/playwright/tools/BrowserApiUrlConfig.spec.mjs b/dev/tests/playwright/tools/BrowserApiUrlConfig.spec.mjs index 53f2e6182..0b54b3103 100644 --- a/dev/tests/playwright/tools/BrowserApiUrlConfig.spec.mjs +++ b/dev/tests/playwright/tools/BrowserApiUrlConfig.spec.mjs @@ -3,8 +3,9 @@ import http from "node:http"; import path from "node:path"; import process from "node:process"; import { expect, test } from "@playwright/test"; -import { startLocalApiServer } from "../../../../src/dev-runtime/server/local-api-server.mjs"; -import { SEED_DB_KEYS } from "../../../../src/dev-runtime/seed/seed-db-keys.mjs"; +import { startLocalApiServer } from "../../../../api/server/local-api-server.mjs"; +import { SEED_DB_KEYS } from "../../../../api/seed/seed-db-keys.mjs"; +import { resolveStaticRouteTarget } from "../../../../api/server/static-web-root.mjs"; import { workspaceV2CoverageReporter } from "../../helpers/workspaceV2CoverageReporter.mjs"; const LIVE_SERVER_ORIGIN = "http://127.0.0.1:5500"; @@ -21,7 +22,7 @@ let localDbRunId = 0; function nextLocalDbStoragePath() { localDbRunId += 1; - return path.join(process.cwd(), "tmp", "local-db", `browser-api-url-config-${process.pid}-${localDbRunId}.local-db-state`); + return path.join(process.cwd(), "dev", "workspace", "tmp", "local-db", `browser-api-url-config-${process.pid}-${localDbRunId}.local-db-state`); } function contentTypeForPath(filePath) { @@ -37,11 +38,6 @@ function contentTypeForPath(filePath) { return "application/octet-stream"; } -function isInsideRepoRoot(repoRoot, absolutePath) { - const relativePath = path.relative(repoRoot, absolutePath); - return relativePath === "" || (!relativePath.startsWith("..") && !path.isAbsolute(relativePath)); -} - async function withEnv(nextEnv, callback) { const previousEnv = {}; Object.keys(nextEnv).forEach((key) => { @@ -72,19 +68,8 @@ async function startStaticLiveServer() { return; } const decodedPath = decodeURIComponent(requestUrl.pathname); - const normalizedPath = path.normalize(decodedPath).replace(/^(\.\.[/\\])+/, ""); - const absolutePath = path.resolve(repoRoot, `.${normalizedPath}`); - if (!isInsideRepoRoot(repoRoot, absolutePath)) { - response.statusCode = 403; - response.end("Forbidden"); - return; - } - let targetPath = absolutePath; - const stat = await fs.stat(targetPath).catch(() => null); - if (stat?.isDirectory()) { - targetPath = path.join(targetPath, "index.html"); - } - const contents = await fs.readFile(targetPath).catch(() => null); + const { targetPath } = await resolveStaticRouteTarget({ decodedPath, repoRoot }); + const contents = targetPath ? await fs.readFile(targetPath).catch(() => null) : null; if (!contents) { response.statusCode = 404; response.end("Not Found"); diff --git a/dev/tests/playwright/tools/BuildPathProgressSimplification.spec.mjs b/dev/tests/playwright/tools/BuildPathProgressSimplification.spec.mjs index 36dbc318b..2cb114895 100644 --- a/dev/tests/playwright/tools/BuildPathProgressSimplification.spec.mjs +++ b/dev/tests/playwright/tools/BuildPathProgressSimplification.spec.mjs @@ -1,5 +1,5 @@ import { expect, test } from "@playwright/test"; -import { MOCK_DB_KEYS } from "../../../../src/dev-runtime/persistence/mock-db-store.js"; +import { MOCK_DB_KEYS } from "../../../../api/persistence/mock-db-store.js"; import { startRepoServer } from "../../helpers/playwrightRepoServer.mjs"; import { clearPlaywrightStorage, installPlaywrightStorageIsolation } from "../../helpers/playwrightStorageIsolation.mjs"; import { workspaceV2CoverageReporter } from "../../helpers/workspaceV2CoverageReporter.mjs"; diff --git a/dev/tests/playwright/tools/EnvironmentBannerCoverage.spec.mjs b/dev/tests/playwright/tools/EnvironmentBannerCoverage.spec.mjs index 08ef9a39c..157a7a132 100644 --- a/dev/tests/playwright/tools/EnvironmentBannerCoverage.spec.mjs +++ b/dev/tests/playwright/tools/EnvironmentBannerCoverage.spec.mjs @@ -1,5 +1,5 @@ import { expect, test } from "@playwright/test"; -import { SEED_DB_KEYS } from "../../../../src/dev-runtime/seed/seed-db-keys.mjs"; +import { SEED_DB_KEYS } from "../../../../api/seed/seed-db-keys.mjs"; import { startRepoServer } from "../../helpers/playwrightRepoServer.mjs"; import { workspaceV2CoverageReporter } from "../../helpers/workspaceV2CoverageReporter.mjs"; diff --git a/dev/tests/playwright/tools/EventsTool.spec.mjs b/dev/tests/playwright/tools/EventsTool.spec.mjs index 39240ef9e..3164129c7 100644 --- a/dev/tests/playwright/tools/EventsTool.spec.mjs +++ b/dev/tests/playwright/tools/EventsTool.spec.mjs @@ -2,7 +2,7 @@ import { expect, test } from "@playwright/test"; import { startRepoServer } from "../../helpers/playwrightRepoServer.mjs"; import { createMessagesPostgresClientStub } from "../../helpers/messagesPostgresClientStub.mjs"; import { clearPlaywrightStorage, installPlaywrightStorageIsolation } from "../../helpers/playwrightStorageIsolation.mjs"; -import { SEED_DB_KEYS } from "../../../../src/dev-runtime/seed/seed-db-keys.mjs"; +import { SEED_DB_KEYS } from "../../../../api/seed/seed-db-keys.mjs"; async function jsonRequest(url, options = {}) { const response = await fetch(url, { diff --git a/dev/tests/playwright/tools/GameConfigurationApiBehavior.spec.mjs b/dev/tests/playwright/tools/GameConfigurationApiBehavior.spec.mjs index 16efcd579..58513aa23 100644 --- a/dev/tests/playwright/tools/GameConfigurationApiBehavior.spec.mjs +++ b/dev/tests/playwright/tools/GameConfigurationApiBehavior.spec.mjs @@ -2,8 +2,8 @@ import { expect, test } from "@playwright/test"; import { readFile } from "node:fs/promises"; import path from "node:path"; import process from "node:process"; -import { createPostgresConnectionClient } from "../../../../src/dev-runtime/persistence/postgres-connection-client.mjs"; -import { SEED_DB_KEYS } from "../../../../src/dev-runtime/seed/seed-db-keys.mjs"; +import { createPostgresConnectionClient } from "../../../../api/persistence/postgres-connection-client.mjs"; +import { SEED_DB_KEYS } from "../../../../api/seed/seed-db-keys.mjs"; import { startRepoServer } from "../../helpers/playwrightRepoServer.mjs"; import { clearPlaywrightStorage, installPlaywrightStorageIsolation } from "../../helpers/playwrightStorageIsolation.mjs"; import { workspaceV2CoverageReporter } from "../../helpers/workspaceV2CoverageReporter.mjs"; diff --git a/dev/tests/playwright/tools/GameCrewFoundation.spec.mjs b/dev/tests/playwright/tools/GameCrewFoundation.spec.mjs index 95754245f..7ebeffe61 100644 --- a/dev/tests/playwright/tools/GameCrewFoundation.spec.mjs +++ b/dev/tests/playwright/tools/GameCrewFoundation.spec.mjs @@ -1,8 +1,8 @@ import { expect, test } from "@playwright/test"; import { readFile } from "node:fs/promises"; import path from "node:path"; -import { createPostgresConnectionClient } from "../../../../src/dev-runtime/persistence/postgres-connection-client.mjs"; -import { SEED_DB_KEYS } from "../../../../src/dev-runtime/seed/seed-db-keys.mjs"; +import { createPostgresConnectionClient } from "../../../../api/persistence/postgres-connection-client.mjs"; +import { SEED_DB_KEYS } from "../../../../api/seed/seed-db-keys.mjs"; import { startRepoServer } from "../../helpers/playwrightRepoServer.mjs"; import { clearPlaywrightStorage, installPlaywrightStorageIsolation } from "../../helpers/playwrightStorageIsolation.mjs"; import { workspaceV2CoverageReporter } from "../../helpers/workspaceV2CoverageReporter.mjs"; diff --git a/dev/tests/playwright/tools/GameDesignApiBehavior.spec.mjs b/dev/tests/playwright/tools/GameDesignApiBehavior.spec.mjs index d8569c2e1..ff743086f 100644 --- a/dev/tests/playwright/tools/GameDesignApiBehavior.spec.mjs +++ b/dev/tests/playwright/tools/GameDesignApiBehavior.spec.mjs @@ -2,8 +2,8 @@ import { expect, test } from "@playwright/test"; import { readFile } from "node:fs/promises"; import path from "node:path"; import process from "node:process"; -import { createPostgresConnectionClient } from "../../../../src/dev-runtime/persistence/postgres-connection-client.mjs"; -import { SEED_DB_KEYS } from "../../../../src/dev-runtime/seed/seed-db-keys.mjs"; +import { createPostgresConnectionClient } from "../../../../api/persistence/postgres-connection-client.mjs"; +import { SEED_DB_KEYS } from "../../../../api/seed/seed-db-keys.mjs"; import { startRepoServer } from "../../helpers/playwrightRepoServer.mjs"; import { clearPlaywrightStorage, installPlaywrightStorageIsolation } from "../../helpers/playwrightStorageIsolation.mjs"; import { workspaceV2CoverageReporter } from "../../helpers/workspaceV2CoverageReporter.mjs"; diff --git a/dev/tests/playwright/tools/GameHubMockRepository.spec.mjs b/dev/tests/playwright/tools/GameHubMockRepository.spec.mjs index e45d8ceab..a392cee98 100644 --- a/dev/tests/playwright/tools/GameHubMockRepository.spec.mjs +++ b/dev/tests/playwright/tools/GameHubMockRepository.spec.mjs @@ -1,7 +1,7 @@ import { expect, test } from "@playwright/test"; import http from "node:http"; import process from "node:process"; -import { MOCK_DB_KEYS } from "../../../../src/dev-runtime/persistence/mock-db-store.js"; +import { MOCK_DB_KEYS } from "../../../../api/persistence/mock-db-store.js"; import { startRepoServer } from "../../helpers/playwrightRepoServer.mjs"; import { clearPlaywrightStorage, installPlaywrightStorageIsolation } from "../../helpers/playwrightStorageIsolation.mjs"; import { workspaceV2CoverageReporter } from "../../helpers/workspaceV2CoverageReporter.mjs"; diff --git a/dev/tests/playwright/tools/GameJourneyTool.spec.mjs b/dev/tests/playwright/tools/GameJourneyTool.spec.mjs index cafea7135..f9708c173 100644 --- a/dev/tests/playwright/tools/GameJourneyTool.spec.mjs +++ b/dev/tests/playwright/tools/GameJourneyTool.spec.mjs @@ -13,9 +13,9 @@ import { GAME_JOURNEY_STATUSES, GAME_JOURNEY_TOOL_OWNERSHIP_AREAS, createGameJourneyMockRepository, -} from "../../../../src/dev-runtime/persistence/tool-repositories/game-journey-mock-repository.js"; -import { createGameJourneyCompletionMetricsStore } from "../../../../src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs"; -import { MOCK_DB_KEYS, getStandaloneMockDbSeedTables } from "../../../../src/dev-runtime/persistence/mock-db-store.js"; +} from "../../../../api/persistence/tool-repositories/game-journey-mock-repository.js"; +import { createGameJourneyCompletionMetricsStore } from "../../../../api/persistence/game-journey-completion-metrics-store.mjs"; +import { MOCK_DB_KEYS, getStandaloneMockDbSeedTables } from "../../../../api/persistence/mock-db-store.js"; const __dirname = path.dirname(fileURLToPath(import.meta.url)); const repoRoot = path.resolve(__dirname, "../../../.."); @@ -1689,7 +1689,7 @@ test("Game Journey source stays separate from notes files and browser persistenc const sourcePaths = [ "toolbox/game-journey/index.html", "assets/toolbox/game-journey/js/index.js", - "src/dev-runtime/persistence/tool-repositories/game-journey-mock-repository.js" + "api/persistence/tool-repositories/game-journey-mock-repository.js" ]; const banned = [ "admin" + "-notes", diff --git a/dev/tests/playwright/tools/IdeaBoardTableNotes.spec.mjs b/dev/tests/playwright/tools/IdeaBoardTableNotes.spec.mjs index dc72434e0..ae389417a 100644 --- a/dev/tests/playwright/tools/IdeaBoardTableNotes.spec.mjs +++ b/dev/tests/playwright/tools/IdeaBoardTableNotes.spec.mjs @@ -1,6 +1,6 @@ import { expect, test } from "@playwright/test"; -import { GAME_JOURNEY_BOOTSTRAP_BUCKETS } from "../../../../src/dev-runtime/persistence/tool-repositories/game-journey-mock-repository.js"; -import { MOCK_DB_KEYS } from "../../../../src/dev-runtime/persistence/mock-db-store.js"; +import { GAME_JOURNEY_BOOTSTRAP_BUCKETS } from "../../../../api/persistence/tool-repositories/game-journey-mock-repository.js"; +import { MOCK_DB_KEYS } from "../../../../api/persistence/mock-db-store.js"; import { isBrowserExtensionNoise } from "../../helpers/browserExtensionNoise.mjs"; import { createGameJourneyCompletionMetricsPostgresClientStub } from "../../helpers/gameJourneyCompletionMetricsPostgresClientStub.mjs"; import { startRepoServer } from "../../helpers/playwrightRepoServer.mjs"; diff --git a/dev/tests/playwright/tools/InputMappingV2Tool.spec.mjs b/dev/tests/playwright/tools/InputMappingV2Tool.spec.mjs index b0f6c07e1..514084095 100644 --- a/dev/tests/playwright/tools/InputMappingV2Tool.spec.mjs +++ b/dev/tests/playwright/tools/InputMappingV2Tool.spec.mjs @@ -1,5 +1,5 @@ import { expect, test } from "@playwright/test"; -import { MOCK_DB_KEYS } from "../../../../src/dev-runtime/persistence/mock-db-store.js"; +import { MOCK_DB_KEYS } from "../../../../api/persistence/mock-db-store.js"; import { startRepoServer } from "../../helpers/playwrightRepoServer.mjs"; import { clearPlaywrightStorage, installPlaywrightStorageIsolation } from "../../helpers/playwrightStorageIsolation.mjs"; import { workspaceV2CoverageReporter } from "../../helpers/workspaceV2CoverageReporter.mjs"; diff --git a/dev/tests/playwright/tools/LoginSessionMode.spec.mjs b/dev/tests/playwright/tools/LoginSessionMode.spec.mjs index 0408c1443..805acd0b7 100644 --- a/dev/tests/playwright/tools/LoginSessionMode.spec.mjs +++ b/dev/tests/playwright/tools/LoginSessionMode.spec.mjs @@ -3,8 +3,8 @@ import http from "node:http"; import path from "node:path"; import process from "node:process"; import { expect, test } from "@playwright/test"; -import { MOCK_DB_KEYS } from "../../../../src/dev-runtime/persistence/mock-db-store.js"; -import { startLocalApiServer } from "../../../../src/dev-runtime/server/local-api-server.mjs"; +import { MOCK_DB_KEYS } from "../../../../api/persistence/mock-db-store.js"; +import { startLocalApiServer } from "../../../../api/server/local-api-server.mjs"; import { isBrowserExtensionNoise } from "../../helpers/browserExtensionNoise.mjs"; import { startRepoServer } from "../../helpers/playwrightRepoServer.mjs"; import { clearPlaywrightStorage, installPlaywrightStorageIsolation } from "../../helpers/playwrightStorageIsolation.mjs"; diff --git a/dev/tests/playwright/tools/MessagesTool.spec.mjs b/dev/tests/playwright/tools/MessagesTool.spec.mjs index 3484467a8..f4a4e92eb 100644 --- a/dev/tests/playwright/tools/MessagesTool.spec.mjs +++ b/dev/tests/playwright/tools/MessagesTool.spec.mjs @@ -3,7 +3,7 @@ import { startRepoServer } from "../../helpers/playwrightRepoServer.mjs"; import { createMessagesPostgresClientStub } from "../../helpers/messagesPostgresClientStub.mjs"; import { clearPlaywrightStorage, installPlaywrightStorageIsolation } from "../../helpers/playwrightStorageIsolation.mjs"; import { workspaceV2CoverageReporter } from "../../helpers/workspaceV2CoverageReporter.mjs"; -import { SEED_DB_KEYS } from "../../../../src/dev-runtime/seed/seed-db-keys.mjs"; +import { SEED_DB_KEYS } from "../../../../api/seed/seed-db-keys.mjs"; const ULID_PATTERN = /^[0-9A-HJKMNP-TV-Z]{26}$/; const TEST_TTS_PROFILE_NAME = "Message Test Profile"; diff --git a/dev/tests/playwright/tools/ObjectsTool.spec.mjs b/dev/tests/playwright/tools/ObjectsTool.spec.mjs index 74e132e67..b1b2497e8 100644 --- a/dev/tests/playwright/tools/ObjectsTool.spec.mjs +++ b/dev/tests/playwright/tools/ObjectsTool.spec.mjs @@ -2,7 +2,7 @@ import { expect, test } from "@playwright/test"; import { startRepoServer } from "../../helpers/playwrightRepoServer.mjs"; import { clearPlaywrightStorage, installPlaywrightStorageIsolation } from "../../helpers/playwrightStorageIsolation.mjs"; import { workspaceV2CoverageReporter } from "../../helpers/workspaceV2CoverageReporter.mjs"; -import { SEED_DB_KEYS } from "../../../../src/dev-runtime/seed/seed-db-keys.mjs"; +import { SEED_DB_KEYS } from "../../../../api/seed/seed-db-keys.mjs"; const TYPE_OPTIONS = ["Collectible", "Custom", "Decoration", "Enemy", "Goal", "Hazard", "Hero", "Platform", "Projectile", "Spawn Point", "Wall"]; const OLD_SAMPLE_PATH_PATTERN = new RegExp(["M" + "VP", "Padd" + "le", "Ba" + "ll"].join("|"), "i"); diff --git a/dev/tests/playwright/tools/OwnerAiCreditsPage.spec.mjs b/dev/tests/playwright/tools/OwnerAiCreditsPage.spec.mjs index 5cc294404..8d583b350 100644 --- a/dev/tests/playwright/tools/OwnerAiCreditsPage.spec.mjs +++ b/dev/tests/playwright/tools/OwnerAiCreditsPage.spec.mjs @@ -1,7 +1,7 @@ import { expect, test } from "@playwright/test"; import fs from "node:fs/promises"; import path from "node:path"; -import { SEED_DB_KEYS } from "../../../../src/dev-runtime/seed/seed-db-keys.mjs"; +import { SEED_DB_KEYS } from "../../../../api/seed/seed-db-keys.mjs"; import { startRepoServer } from "../../helpers/playwrightRepoServer.mjs"; import { workspaceV2CoverageReporter } from "../../helpers/workspaceV2CoverageReporter.mjs"; diff --git a/dev/tests/playwright/tools/OwnerMembershipsPage.spec.mjs b/dev/tests/playwright/tools/OwnerMembershipsPage.spec.mjs index 042c09397..316458508 100644 --- a/dev/tests/playwright/tools/OwnerMembershipsPage.spec.mjs +++ b/dev/tests/playwright/tools/OwnerMembershipsPage.spec.mjs @@ -1,7 +1,7 @@ import { expect, test } from "@playwright/test"; import { startRepoServer } from "../../helpers/playwrightRepoServer.mjs"; import { workspaceV2CoverageReporter } from "../../helpers/workspaceV2CoverageReporter.mjs"; -import { SEED_DB_KEYS } from "../../../../src/dev-runtime/seed/seed-db-keys.mjs"; +import { SEED_DB_KEYS } from "../../../../api/seed/seed-db-keys.mjs"; async function setSessionUser(server, userKey) { await fetch(`${server.baseUrl}/api/session/user`, { diff --git a/dev/tests/playwright/tools/PaletteToolMockRepository.spec.mjs b/dev/tests/playwright/tools/PaletteToolMockRepository.spec.mjs index f841bbabe..39d280684 100644 --- a/dev/tests/playwright/tools/PaletteToolMockRepository.spec.mjs +++ b/dev/tests/playwright/tools/PaletteToolMockRepository.spec.mjs @@ -1,11 +1,11 @@ import { expect, test } from "@playwright/test"; -import { MOCK_DB_KEYS } from "../../../../src/dev-runtime/persistence/mock-db-store.js"; +import { MOCK_DB_KEYS } from "../../../../api/persistence/mock-db-store.js"; import { PALETTE_WORKSPACE_PATH, PALETTE_TOOL_TABLES, createGameWorkspacePaletteRepository, validatePaletteWorkspacePayload -} from "../../../../src/dev-runtime/persistence/tool-repositories/palette-workspace-repository.js"; +} from "../../../../api/persistence/tool-repositories/palette-workspace-repository.js"; import { startRepoServer } from "../../helpers/playwrightRepoServer.mjs"; import { clearPlaywrightStorage, installPlaywrightStorageIsolation } from "../../helpers/playwrightStorageIsolation.mjs"; import { expectCompactToolFormControls } from "../../helpers/toolFormControlAssertions.mjs"; diff --git a/dev/tests/playwright/tools/PublicMarketplacePage.spec.mjs b/dev/tests/playwright/tools/PublicMarketplacePage.spec.mjs index fe725ef9c..cfaf7e5a6 100644 --- a/dev/tests/playwright/tools/PublicMarketplacePage.spec.mjs +++ b/dev/tests/playwright/tools/PublicMarketplacePage.spec.mjs @@ -1,5 +1,5 @@ import { expect, test } from "@playwright/test"; -import { SEED_DB_KEYS } from "../../../../src/dev-runtime/seed/seed-db-keys.mjs"; +import { SEED_DB_KEYS } from "../../../../api/seed/seed-db-keys.mjs"; import { startRepoServer } from "../../helpers/playwrightRepoServer.mjs"; import { workspaceV2CoverageReporter } from "../../helpers/workspaceV2CoverageReporter.mjs"; diff --git a/dev/tests/playwright/tools/PublicMembershipsPage.spec.mjs b/dev/tests/playwright/tools/PublicMembershipsPage.spec.mjs index b59afea0e..807559a3c 100644 --- a/dev/tests/playwright/tools/PublicMembershipsPage.spec.mjs +++ b/dev/tests/playwright/tools/PublicMembershipsPage.spec.mjs @@ -1,6 +1,6 @@ import { expect, test } from "@playwright/test"; import { startRepoServer } from "../../helpers/playwrightRepoServer.mjs"; -import { SEED_DB_KEYS } from "../../../../src/dev-runtime/seed/seed-db-keys.mjs"; +import { SEED_DB_KEYS } from "../../../../api/seed/seed-db-keys.mjs"; async function openMembershipsPage(page, options = {}) { if (options.viewport) { diff --git a/dev/tests/playwright/tools/RootToolsFutureState.spec.mjs b/dev/tests/playwright/tools/RootToolsFutureState.spec.mjs index 8fa08d4cc..8ccbaab95 100644 --- a/dev/tests/playwright/tools/RootToolsFutureState.spec.mjs +++ b/dev/tests/playwright/tools/RootToolsFutureState.spec.mjs @@ -1,6 +1,6 @@ import http from "node:http"; import { expect, test } from "@playwright/test"; -import { MOCK_DB_KEYS } from "../../../../src/dev-runtime/persistence/mock-db-store.js"; +import { MOCK_DB_KEYS } from "../../../../api/persistence/mock-db-store.js"; import { startRepoServer } from "../../helpers/playwrightRepoServer.mjs"; import { clearPlaywrightStorage, installPlaywrightStorageIsolation } from "../../helpers/playwrightStorageIsolation.mjs"; import { workspaceV2CoverageReporter } from "../../helpers/workspaceV2CoverageReporter.mjs"; diff --git a/dev/tests/playwright/tools/TagsTool.spec.mjs b/dev/tests/playwright/tools/TagsTool.spec.mjs index f9ce4f841..778e03b66 100644 --- a/dev/tests/playwright/tools/TagsTool.spec.mjs +++ b/dev/tests/playwright/tools/TagsTool.spec.mjs @@ -1,8 +1,8 @@ import { readFile } from "node:fs/promises"; import path from "node:path"; import { expect, test } from "@playwright/test"; -import { createPostgresConnectionClient } from "../../../../src/dev-runtime/persistence/postgres-connection-client.mjs"; -import { SEED_DB_KEYS } from "../../../../src/dev-runtime/seed/seed-db-keys.mjs"; +import { createPostgresConnectionClient } from "../../../../api/persistence/postgres-connection-client.mjs"; +import { SEED_DB_KEYS } from "../../../../api/seed/seed-db-keys.mjs"; import { startRepoServer } from "../../helpers/playwrightRepoServer.mjs"; import { clearPlaywrightStorage, installPlaywrightStorageIsolation } from "../../helpers/playwrightStorageIsolation.mjs"; import { workspaceV2CoverageReporter } from "../../helpers/workspaceV2CoverageReporter.mjs"; diff --git a/dev/tests/playwright/tools/TextToSpeechFunctional.spec.mjs b/dev/tests/playwright/tools/TextToSpeechFunctional.spec.mjs index 9395aac29..0df7550b4 100644 --- a/dev/tests/playwright/tools/TextToSpeechFunctional.spec.mjs +++ b/dev/tests/playwright/tools/TextToSpeechFunctional.spec.mjs @@ -2,7 +2,7 @@ import { expect, test } from "@playwright/test"; import { startRepoServer } from "../../helpers/playwrightRepoServer.mjs"; import { createMessagesPostgresClientStub } from "../../helpers/messagesPostgresClientStub.mjs"; import { workspaceV2CoverageReporter } from "../../helpers/workspaceV2CoverageReporter.mjs"; -import { SEED_DB_KEYS } from "../../../../src/dev-runtime/seed/seed-db-keys.mjs"; +import { SEED_DB_KEYS } from "../../../../api/seed/seed-db-keys.mjs"; test.use({ trace: "off" }); diff --git a/dev/tests/playwright/tools/ToolboxAdminMetadataSsot.spec.mjs b/dev/tests/playwright/tools/ToolboxAdminMetadataSsot.spec.mjs index 4f66a0b3b..6add8239a 100644 --- a/dev/tests/playwright/tools/ToolboxAdminMetadataSsot.spec.mjs +++ b/dev/tests/playwright/tools/ToolboxAdminMetadataSsot.spec.mjs @@ -1,5 +1,5 @@ import { expect, test } from "@playwright/test"; -import { MOCK_DB_KEYS } from "../../../../src/dev-runtime/persistence/mock-db-store.js"; +import { MOCK_DB_KEYS } from "../../../../api/persistence/mock-db-store.js"; import { startRepoServer } from "../../helpers/playwrightRepoServer.mjs"; import { clearPlaywrightStorage, installPlaywrightStorageIsolation } from "../../helpers/playwrightStorageIsolation.mjs"; import { workspaceV2CoverageReporter } from "../../helpers/workspaceV2CoverageReporter.mjs"; diff --git a/dev/tests/playwright/tools/ToolboxRoutePages.spec.mjs b/dev/tests/playwright/tools/ToolboxRoutePages.spec.mjs index 3bf9d1c0b..648cfa758 100644 --- a/dev/tests/playwright/tools/ToolboxRoutePages.spec.mjs +++ b/dev/tests/playwright/tools/ToolboxRoutePages.spec.mjs @@ -1,5 +1,5 @@ import { expect, test } from "@playwright/test"; -import { MOCK_DB_KEYS } from "../../../../src/dev-runtime/persistence/mock-db-store.js"; +import { MOCK_DB_KEYS } from "../../../../api/persistence/mock-db-store.js"; import { isBrowserExtensionNoise } from "../../helpers/browserExtensionNoise.mjs"; import { startRepoServer } from "../../helpers/playwrightRepoServer.mjs"; import { workspaceV2CoverageReporter } from "../../helpers/workspaceV2CoverageReporter.mjs"; diff --git a/dev/tests/playwright/tools/ToolboxSelectedGameStatusBar.spec.mjs b/dev/tests/playwright/tools/ToolboxSelectedGameStatusBar.spec.mjs index 14d507ca9..d057acb86 100644 --- a/dev/tests/playwright/tools/ToolboxSelectedGameStatusBar.spec.mjs +++ b/dev/tests/playwright/tools/ToolboxSelectedGameStatusBar.spec.mjs @@ -1,6 +1,6 @@ import { expect, test } from "@playwright/test"; import process from "node:process"; -import { MOCK_DB_KEYS } from "../../../../src/dev-runtime/persistence/mock-db-store.js"; +import { MOCK_DB_KEYS } from "../../../../api/persistence/mock-db-store.js"; import { startRepoServer } from "../../helpers/playwrightRepoServer.mjs"; import { clearPlaywrightStorage, installPlaywrightStorageIsolation } from "../../helpers/playwrightStorageIsolation.mjs"; import { workspaceV2CoverageReporter } from "../../helpers/workspaceV2CoverageReporter.mjs"; diff --git a/dev/tests/tools/MessagesPlaybackSource.test.mjs b/dev/tests/tools/MessagesPlaybackSource.test.mjs index dbc800206..046c165d0 100644 --- a/dev/tests/tools/MessagesPlaybackSource.test.mjs +++ b/dev/tests/tools/MessagesPlaybackSource.test.mjs @@ -33,7 +33,7 @@ test("Messages wires profile dropdowns through the Text To Speech profile contra }); test("Messages dev runtime does not import browser Text To Speech UI modules", async () => { - const source = await readFile(new URL("../../../src/dev-runtime/messages/messages-postgres-service.mjs", import.meta.url), "utf8"); + const source = await readFile(new URL("../../../api/messages/messages-postgres-service.mjs", import.meta.url), "utf8"); assert.equal(source.includes("toolbox/text-to-speech/text2speech.js"), false); assert.equal(source.includes("createMessageStudioDefaultTtsProfiles"), false); diff --git a/src/dev-runtime/DEV_RUNTIME_BOUNDARY.md b/src/dev-runtime/DEV_RUNTIME_BOUNDARY.md deleted file mode 100644 index 51b8ee73c..000000000 --- a/src/dev-runtime/DEV_RUNTIME_BOUNDARY.md +++ /dev/null @@ -1,16 +0,0 @@ -# Dev Runtime Boundary - -`src/dev-runtime` contains local development runtime implementation for the browser-visible Local API, seeded product data, provider stubs, storage adapters, database adapters, and support services used by repository validation. - -It is intentionally not `tests/dev-runtime`: - -- `src/dev-runtime` serves runtime behavior that browser pages and local API routes can exercise during development and targeted validation. -- `tests/dev-runtime` contains test files that validate that behavior. -- Moving the implementation into `tests/dev-runtime` would make development pages depend on test-only code and would blur the Browser -> Server API -> Data Source boundary. - -Deployment boundary: - -- DEV validation may execute `src/dev-runtime` through local server commands. -- UAT and PROD bundles must not import, bundle, or deploy `src/dev-runtime`. -- Browser pages, Theme V2 scripts, toolbox pages, and `src/engine` runtime code must use declared API/service contracts instead of importing `src/dev-runtime` directly. -- If a dev-only adapter is needed by a browser page, expose it through the Local API contract while keeping the implementation under `src/dev-runtime`. diff --git a/src/dev-runtime/guest-seeds/tool-metadata-inventory.js b/src/dev-runtime/guest-seeds/tool-metadata-inventory.js deleted file mode 100644 index f2da13bfe..000000000 --- a/src/dev-runtime/guest-seeds/tool-metadata-inventory.js +++ /dev/null @@ -1 +0,0 @@ -export * from "../../shared/toolbox/tool-metadata-inventory.js";