feat(pro): generalize pro tier to multi-surface extension points
Move the pro mount decnet/services/pro/ -> decnet/pro/ so the Professional tier
can contribute to more than honeypots. The core wires each surface only when
decnet/pro/ is present (absence stays the entitlement gate):
* services — registry scans decnet/pro/services/ (was decnet/services/pro/)
* API routes — decnet/pro/routes.py exposes ROUTERS, mounted under /api/v1
* web pages — Vite aliases @pro to the pro frontend (community -> empty stub),
App.tsx maps proRoutes into <Route>s, Layout renders a
PROFESSIONAL nav group; both tree-shake out of the community build
Frontend gate mirrors the existing VITE_DECNET_DEVELOPER tree-shake pattern.
Tests: registry + router seams (backend), empty-stub contract (frontend).
This commit is contained in:
10
decnet_web/src/pro/pro.test.ts
Normal file
10
decnet_web/src/pro/pro.test.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
import { proRoutes } from '@pro';
|
||||
|
||||
// In the community build, `@pro` resolves to the stub: no Professional pages,
|
||||
// so App's route map and Layout's nav group both tree-shake to nothing.
|
||||
describe('pro tier — community build', () => {
|
||||
it('ships no pro routes', () => {
|
||||
expect(proRoutes).toEqual([]);
|
||||
});
|
||||
});
|
||||
8
decnet_web/src/pro/stub.ts
Normal file
8
decnet_web/src/pro/stub.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
// Community build: no Professional pages. `@pro` resolves here unless the build
|
||||
// sets VITE_DECNET_PRO=1 with decnet/pro/web/ present, in which case Vite
|
||||
// aliases `@pro` to the real registry. proRoutes being empty lets the router
|
||||
// and nav tree-shake the pro surface out of the community bundle.
|
||||
import type { ProRoute } from './types';
|
||||
|
||||
export const proRoutes: ProRoute[] = [];
|
||||
15
decnet_web/src/pro/types.ts
Normal file
15
decnet_web/src/pro/types.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
// Contract for Professional-tier UI pages. The pro build aliases `@pro` to the
|
||||
// real registry in decnet/pro/web/; the community build resolves it to ./stub.
|
||||
import type { ReactElement, ReactNode } from 'react';
|
||||
|
||||
export interface ProRoute {
|
||||
/** Router path, e.g. "/pro/intel". Convention: prefix pro routes with /pro. */
|
||||
path: string;
|
||||
/** Sidebar label. */
|
||||
label: string;
|
||||
/** Sidebar icon (lucide-react element), optional. */
|
||||
icon?: ReactNode;
|
||||
/** Page element rendered at `path`. May be a lazy component (App wraps Suspense). */
|
||||
element: ReactElement;
|
||||
}
|
||||
Reference in New Issue
Block a user