Skip to content

Refactor apps/ui-community layout sections into @ocom/ui-community-route-* workspace packages #191

@nnoce14

Description

@nnoce14

Summary

Refactor apps/ui-community so that each existing layout section under src/components/layouts/ becomes its own workspace package under packages/ocom/, while leaving apps/ui-community as the thin composition/bootstrap app.

This refactor must preserve the current runtime behavior and routing structure exactly. The goal is packaging and separation of concerns, not a router redesign.


Repo-specific constraints

Current section inventory

Inspect apps/ui-community/src/components/layouts/ and use the actual section directories found there as the package list for this task.

At the time of writing, the section directories are:

  • accounts
  • admin
  • root

There is also a shared/components subtree under layouts; that is not a section package target for this task and should remain shared app code unless a later task extracts it into a dedicated shared package.

Current routing architecture must stay intact

apps/ui-community currently uses:

  • BrowserRouter in src/main.tsx
  • <Routes> / <Route> composition in src/App.tsx
  • direct imports of Accounts, Admin, and Root from src/components/layouts/...

Do not convert this app to createBrowserRouter, RouteObject[], route loaders, or a different routing model as part of this task.

The route tree and URLs must remain identical. Only the origin of the section components changes.

Package compilation strategy: JIT workspace packages

These new route packages are Vite-consumed UI packages only. They should be implemented as just-in-time internal packages:

  • no compiled dist/ output
  • no build script
  • package exports should point directly to TypeScript source
  • Vite should compile them inline through workspace linking

Do not introduce Vite aliasing or optimizeDeps workarounds unless the refactor proves they are strictly necessary.

Type-checking requirement

Because these JIT packages do not have a build step, add a dedicated check-types script (tsc --noEmit) to each new route package and wire a repo-level check-types task in turbo.json.

This is new infrastructure for these JIT route packages. Keep it scoped to this effort.


Implementation requirements

1. Create one package per section

Create the following packages under packages/ocom/:

  • packages/ocom/ui-community-route-accounts
  • packages/ocom/ui-community-route-admin
  • packages/ocom/ui-community-route-root

Each package should follow this structure:

packages/ocom/ui-community-route-<section>/
├── package.json
├── tsconfig.json
└── src/
    └── index.ts

package.json

Use a JIT/internal-package shape similar to:

{
  "name": "@ocom/ui-community-route-<section>",
  "version": "0.0.1",
  "private": true,
  "type": "module",
  "exports": {
    ".": "./src/index.ts"
  },
  "scripts": {
    "check-types": "tsc --noEmit",
    "lint": "biome lint ./src",
    "test": "vitest run"
  },
  "dependencies": {},
  "devDependencies": {
    "@cellix/config-typescript": "workspace:*",
    "typescript": "catalog:"
  }
}

Rules:

  • Do not add a build script
  • Do not add files, dist, or compiled output
  • Only declare dependencies actually used by the moved section
  • Follow existing repo conventions for dependency versions:
    • typescript: use workspace catalog
    • react-router-dom: use workspace catalog if needed
    • react, react-dom, @apollo/client, etc.: do not assume catalog usage; mirror the existing workspace convention already used in comparable UI packages unless there is a deliberate repo-wide change in the same PR

2. Add package TypeScript configs

Each route package needs a tsconfig.json for browser/React source type-checking.

Match the current apps/ui-community compiler options unless a package-local change is required for JIT type-checking. At minimum, preserve alignment with the current app settings for jsx, lib, exactOptionalPropertyTypes, and skipLibCheck.

Important:

  • Start from the same base convention used by apps/ui-community
  • Do not assume a @cellix/config-typescript/react export exists
  • First inspect packages/cellix/typescript-config and confirm what presets are actually exported
  • If no dedicated React/browser preset exists, extend the same base preset used by apps/ui-community and set the necessary React/browser compiler options locally

Required properties:

  • noEmit: true
  • include src/**/*.ts and src/**/*.tsx
  • no outDir
  • no tsBuildInfoFile
  • no composite
  • no project references
  • no compilerOptions.paths

Example shape only:

{
  "extends": "@cellix/config-typescript/base",
  "compilerOptions": {
    "noEmit": true,
    "jsx": "react-jsx",
    "lib": ["ES2023", "DOM"],
    "exactOptionalPropertyTypes": false,
    "skipLibCheck": true
  },
  "include": ["src/**/*.ts", "src/**/*.tsx"]
}

Use the real minimal config required by the repo after inspection.

3. Export section entrypoints, not a new router abstraction

Each package should export the existing top-level section component for that section.

Examples:

  • @ocom/ui-community-route-accounts exports Accounts
  • @ocom/ui-community-route-admin exports Admin
  • @ocom/ui-community-route-root exports Root

Do not redesign the packages around RouteObject[] in this task unless the existing app already uses that pattern somewhere relevant. Preserve the current JSX-router composition model.

4. Move section source files

Move each section from:

  • apps/ui-community/src/components/layouts/accounts/
  • apps/ui-community/src/components/layouts/admin/
  • apps/ui-community/src/components/layouts/root/

into its corresponding package under src/.

Update imports accordingly.

Cross-boundary import rule

If a file inside one section imports code from:

  • another section directory, or
  • app-local code outside the section that is not obviously shared bootstrap code

do not silently duplicate or restructure that code during this task.

Instead:

  • keep the shared code in apps/ui-community if that is the smallest safe change, or
  • leave a clear PR note describing the boundary leak and what should be extracted in a follow-up task

This task is about extracting the existing sections cleanly, not inventing new shared-package boundaries mid-flight.

5. Update apps/ui-community to consume the new packages

package.json

Add the new route packages as workspace dependencies.

src/App.tsx

Replace imports from:

  • ./components/layouts/accounts/...
  • ./components/layouts/admin/...
  • ./components/layouts/root/...

with imports from the new @ocom/ui-community-route-* packages.

Keep the current route structure exactly the same.

The current route composition in apps/ui-community/src/App.tsx is:

  • top-level path="*" renders Root
  • top-level path="/auth-redirect" renders the auth landing flow
  • top-level path="/community/*" renders the authenticated community section
  • inside the community section:
    • path="/" renders Accounts
    • path="/accounts/*" renders Accounts
    • path="/:communityId/admin/:memberId/*" renders Admin

Preserve those exact paths and section ownership. Do not add, remove, rename, or restructure routes as part of this task.

What must remain in apps/ui-community

These stay in the app and do not move into section packages:

  • main.tsx
  • overall app bootstrap
  • BrowserRouter
  • App.tsx
  • Apollo wiring / providers
  • auth / OIDC providers
  • Ant Design ConfigProvider / app shell wiring
  • HelmetProvider
  • ThemeProvider / theme context wiring
  • environment/config wiring
  • any truly shared UI/bootstrap code used across sections

6. Add check-types support to turbo.json

Add repo tasks for the new JIT package type-check flow.

Recommended pattern:

{
  "tasks": {
    "topo": {
      "dependsOn": ["^topo"]
    },
    "check-types": {
      "dependsOn": ["topo"],
      "inputs": ["src/**/*.ts", "src/**/*.tsx", "tsconfig.json", "tsconfig.*.json"]
    }
  }
}

Only the new JIT route packages need the check-types script as part of this task.

Do not churn unrelated packages unless required.


Acceptance criteria

  • pnpm install && turbo run build passes
  • turbo run check-types passes for all new @ocom/ui-community-route-* packages
  • turbo run dev starts successfully and apps/ui-community still serves the same routes at the same paths
  • top-level * still renders Root
  • /auth-redirect still renders the auth landing flow
  • /community/ and /community/accounts/* still render Accounts
  • /community/:communityId/admin/:memberId/* still renders Admin
  • editing a .tsx file inside any new route package triggers Vite HMR in apps/ui-community without needing a package build step
  • no new route package has a build script
  • no new route package emits dist/
  • apps/ui-community/src/components/layouts/accounts, admin, and root are removed from the app after extraction
  • any cross-section or app-boundary dependency that blocks a clean move is explicitly documented in the PR and not silently papered over

Notes for the implementer

This task is intentionally not a router modernization task.

Do not:

  • migrate to createBrowserRouter
  • introduce route loaders/actions
  • switch to RouteObject[]
  • introduce TypeScript path aliases
  • add Vite alias hacks unless proven necessary
  • broaden the refactor into a shared-components architecture rewrite

The target outcome is a thin bootstrap app plus JIT-consumed route packages with identical behavior.

Metadata

Metadata

Labels

enhancementNew feature or request

Projects

Status

Todo

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions