82 lines
31 KiB
Markdown
82 lines
31 KiB
Markdown
# Feature Inventory fuer Boilerplate-Pruning
|
|
|
|
Last reconciled: 2026-05-28. Quelle: `BOILERPLATE-PLAN.md`, `apps/web/app/routes`, `apps/web/app/modules`, Sidebars, Root-`package.json` und der aktuelle Repo-State-Snapshot `docs/architecture-migration-status.md`. Ziel ist eine praktische Entscheidungshilfe, welche Produktflaechen im Standard-Boilerplate bleiben, optionalisiert oder entfernt werden sollten.
|
|
|
|
Statushinweis: Dieses Inventar beschreibt den Dokumentations-/Manifest-Vertrag fuer R003 und ist kein Nachweis, dass alle genannten Codeflaechen bereits geloescht oder paketiert wurden. Der aktuelle Architecture Closure-Abschluss fuer API-, Worker- und Package-Boundaries, Feature-Manifeste und Bundle-/Performance-Evidenz ist in `docs/architecture-migration-status.md` dokumentiert.
|
|
|
|
Maschinenlesbare Feature-Vertraege liegen in `docs/feature-manifests/`. Sie spiegeln diese Inventarentscheidung als JSON-Manifeste fuer Core-, Plugin- und Removal-Grenzen und werden durch `apps/web/app/application/featureManifests.test.ts` validiert. Die Klassifikationen sind bewusst mehrstufig: `core` bleibt die neutrale SaaS-Basis, `product-core` ist das aktuell mitgelieferte CRM-SaaS-Showcase, `plugin-candidates` beschreibt die Extraktionsgrenzen fuer produktnahe Flaechen, und `remove-candidate` beschreibt direkte Pruning-Ziele statt dauerhaft unterstuetzte Legacy-Flaechen. Ein Modul kann deshalb heute im Product Core aktiv sein und trotzdem als Plugin-Kandidat markiert bleiben, wenn die naechste saubere Grenze eine optionale Auskopplung ist.
|
|
|
|
## Manifest-Decision: Pruned Core statt Full-Boilerplate
|
|
|
|
Feature Manifest entscheidet gegen eine Full-Boilerplate-Retention als Dauerzustand: Der Standard ist ein pruned core plus versionierter Product Core fuer das CRM-SaaS-Showcase. `core` bleibt die aktive Boilerplate-Basis; `product-core` beschreibt Blueprint-, Plan-, Custom-Plan-, Tenant-Override- und Tenant-Rollen-Gates fuer CRM-SaaS-Produktmodule; `plugin-candidate` beschreibt nur noch Extraktionsvertraege fuer optionale Produktflaechen ausserhalb dieses Product Core; `remove-candidate` beschreibt Loesch- oder Review-Vertraege fuer Flaechen, die nicht als dauerhaft unterstuetztes Legacy-Verhalten fortgefuehrt werden sollen. Die Manifeste sind Planungs- und Runtime-Guardrails fuer diese naechsten Schritte, aber kein Beleg, dass jede markierte Flaeche bereits aus dem aktuellen Root-Runtime-Code entfernt oder als Plugin ausgelagert wurde.
|
|
|
|
## Core behalten
|
|
|
|
| Feature | Rationale | Wahrscheinliche Codebereiche |
|
|
| -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
| Auth, Accounts, Tenants, Rollen/Rechte | Basis fuer jede SaaS/App-Installation; Admin- und Tenant-Flows haengen daran. | `apps/web/app/routes/login.tsx`, `register.tsx`, `forgot-password.tsx`, `reset.tsx`, `verify.$id.tsx`, `invitation.$id.tsx`, `apps/web/app/routes/admin/accounts*`, `apps/web/app/routes/app.$tenant/settings/*`, `apps/web/app/modules/users`, `apps/web/app/utils/services/authService.ts`, `rolesAndPermissionsService.ts` |
|
|
| Tenant-App Shell, Dashboard, Settings | Kernprodukt braucht eine stabile App- und Admin-Huelle; Routing nutzt `appPath`, `adminPath` und kanonische Host-Helper. | `apps/web/app/routes/app.$tenant.tsx`, `apps/web/app/routes/app.$tenant/dashboard.tsx`, `apps/web/app/routes/app.$tenant/settings*`, `apps/web/app/application/sidebar/AppSidebar.tsx`, `apps/web/app/components/layouts/sidebars/*` |
|
|
| Admin Shell und System Settings | Notwendig fuer Betrieb, Nutzerverwaltung, Pricing-Konfiguration und Diagnostik. | `apps/web/app/routes/admin.tsx`, `apps/web/app/routes/admin/dashboard.tsx`, `apps/web/app/routes/admin/settings*`, `apps/web/app/application/sidebar/AdminSidebar.tsx` |
|
|
| API-Grundlage und Keys | Plan sieht API-Split vor; Auth-, Docs-, Accounts-, Key-Validation- und Usage-Endpunkte liegen in `apps/api`; Web-Routen bleiben UI/Settings-Surfaces. | `apps/api/src/app.ts`, `/v1/api-keys/validate`, `/v1/usage`, `apps/web/app/routes/admin/api/*`, `apps/web/app/routes/app.$tenant/settings/api/*`, `apps/web/app/modules/api` |
|
|
| DB/ORM-Schicht und Rows-Basis | Viele Features bauen auf Prisma, Entities und Rows; vor Entfernung anderer Features als Datenfundament stabilisieren. | `packages/db`, `prisma`, `apps/web/app/modules/rows`, `apps/web/app/utils/db/**`, `apps/web/app/modules/templates/defaultEntityTemplates.ts` |
|
|
| Transactional Email | Passwort-Reset, Einladungen und Systemmails sind Core; Mailjet ist der einzige Runtime-Provider. | `apps/web/app/modules/emails`, `apps/web/app/utils/services/emailService.ts`, `packages/mail`, dep `@toolctrl/mail` |
|
|
| Billing/Subscriptions | Fuer SaaS-Boilerplate meist Core, aber bewusst minimal halten; Stripe-Anbindung, Admin-Pricing-Settings und Tenant-Subscribe bleiben Standard; Public-Marketing-Pricing ist entfernt. | `subscribe.$tenant*`, `apps/web/app/routes/app.$tenant/settings/subscription.tsx`, `apps/web/app/routes/admin/settings/pricing*`, `apps/api/src/app.ts` `/v1/billing/stripe/webhooks`, `apps/web/app/application/pricing`, dep `stripe` |
|
|
| i18n | Mandatory, Deutsch Default; Runtime-Konfiguration liegt ueber `@toolctrl/i18n`, Locale-Dateien bleiben unter `apps/web/public/locales`. | `packages/i18n`, `apps/web/app/locale/*`, Translation-Dateien, `i18next*` deps |
|
|
| UI-Primitives/Layout | Core als Adapter-Ziel (`packages/ui`), aber gemischte UI-Quellen spaeter konsolidieren. | `apps/web/app/components/ui`, `packages/ui`, `apps/web/app/components/layouts`, Radix/shadcn deps, `lucide-react` |
|
|
|
|
## Optional / Plugin / Admin-Preview
|
|
|
|
| Feature | Rationale | Wahrscheinliche Codebereiche |
|
|
| ------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
| CRM | Aktuell Teil des versionierten `product-core` CRM-SaaS-Showcase, aber wegen default entities `company/contact/opportunity` und Email-Marketing-Kopplung zugleich ein Extraktionskandidat fuer spaetere optionale Verticals. Kanonische Feature Decision baseline-Entscheidung: `docs/feature-decisions/crm-decision-report.md`. Die Route-Codeflaechen bleiben als Plugin-Kandidaten inventarisiert, ohne zu behaupten, dass CRM aus dem heutigen Product Core entfernt ist. | `apps/web/app/modules/crm`, `apps/web/app/routes/admin/crm*`, `apps/web/app/routes/app.$tenant/crm*`, `apps/web/app/modules/templates/defaultEntityTemplates.ts`, Sidebars |
|
|
| Email Marketing/Newsletter | Kanonische Feature Decision flow-Entscheidung: `docs/feature-decisions/email-marketing-decision-report.md`, Decision `extract-plugin`. Als Plugin halten; aktuelle Audience-Quelle sind CRM contacts oder spaeter eine Plugin-Audience. Core bleibt nur transactional mail. | `apps/web/app/modules/emailMarketing`, `apps/web/app/routes/admin/email-marketing*`, `apps/web/app/routes/app.$tenant/email-marketing*` |
|
|
| Email Sequences | Foundation/Admin-Preview, kein Plugin-Kandidat im aktuellen Manifest-Vertrag und kein Core-Transactional-Mail-Verhalten. Delayed-Step-Scheduling, Queue-Enqueueing, bundled Template-Renderer, `@toolctrl/mail` Mailjet-Adapter und signed Mailjet bounce/rejection ingress existieren; Production-Delivery bleibt durch Seed-Daten, Stats-Aggregation-Cron/Persistenz, provider delivery/open/click reconciliation evidence beyond the in-repo tracking routes, E2E und Scheduler-/Deploy-Evidenz blockiert. Kanonischer Status: `docs/features/email-sequences.md`; Produktion bleibt mit `MARKETING_SEQUENCES_ENABLED=false` empfohlen, bis diese Follow-ups landen. | `apps/web/app/routes/admin/email-sequences*`, `packages/email-sequences`, `packages/email-templates`, `apps/worker/src/jobs/email-sequence-*`, `apps/worker/src/jobs/lead-stale-trigger.ts`, `apps/worker/src/jobs/trial-expiring-trigger.ts`, `prisma/schema/emailSequences.prisma` |
|
|
| Workflow Engine | Aktuell als Product-Core-Flaeche und Boilerplate-Workflow-Beispiel aktiv, langfristig aber nach D009 (`docs/feature-decisions/kb-widgets-workflow-marketing-decision-report.md`) ein `extract-plugin`-Kandidat. Die produktionsnahe Worker/Queue-Boundary wird deshalb im Root weiter gehaertet, waehrend Schema-, API- und Worker-Grenzen extraktionsfaehig bleiben muessen. | `apps/web/app/modules/workflowEngine`, `apps/web/app/routes/admin/__workflows/*`, `apps/web/app/routes/app.$tenant/__workflows/*`, `apps/web/app/routes/internal/api/__workflows/*`, `prisma/schema/workflows.prisma`, direkte deps `@xyflow/react`, `dagre`; `eventsource-parser` ist nur transitiv im Lockfile sichtbar. |
|
|
| Knowledge Base | Support-/Docs-Produktflaeche mit Public-Docs- und Daten-Sichtbarkeitsgrenze. Fuer das CRM-SaaS-Showcase kann sie Product-Core sein; nach D009 (`docs/feature-decisions/kb-widgets-workflow-marketing-decision-report.md`) bleibt sie zugleich `extract-plugin`-Kandidat. Admin-/Help-Route-Trees duerfen deshalb nur ueber dokumentierte Gates sichtbar werden; `/docs` bleibt die aktive public Docs-Flaeche. | `apps/web/app/modules/knowledgeBase`, `apps/web/app/routes/docs/*`, `apps/web/app/routes/admin/knowledge-base*`, `apps/web/app/routes/help/*`, `prisma/schema/knowledgeBase.prisma` |
|
|
| Portals/Sites | Kanonische Feature Decision/S03-Entscheidung D007: `docs/feature-decisions/portals-sites-decision-report.md`, Decision `extract-plugin`. Mehr Produktplattform als Boilerplate-Core; als customer portal/site-builder Plugin halten. Die Route-Codeflaechen sind als Plugin-Kandidaten inventarisiert, aber in der Default-Core-Route-Discovery deaktiviert. | `apps/web/app/modules/portals`, `apps/web/app/modules/sites`, `apps/web/app/routes/app.$tenant/__portals/*`, `apps/web/app/routes/app.$tenant/sites/*`, `apps/web/app/routes/admin/portals.tsx` |
|
|
| Analytics/Metrics | Core braucht ggf. minimale Observability, aber product analytics UI/collection sollte opt-in sein. | `apps/web/app/modules/analytics`, `apps/web/app/modules/metrics`, `apps/web/app/routes/admin/analytics*`, `apps/web/app/routes/admin/metrics*`, `apps/api/src/app.ts` `/v1/analytics/*`, dep `recharts` |
|
|
| Events/Webhooks/Audit Trails | Domain events sind fuer Integrationen/Workers sinnvoll; Admin-Event-Browser und entity webhooks koennen optional sein. Webhook-Attempt-Retry liegt in `apps/api` unter `/v1/events/webhooks/attempts/:id`; alte public Demo-ACK-Routen wurden aus dem Core entfernt. | `apps/web/app/modules/events`, `apps/web/app/routes/admin/events*`, `apps/web/app/routes/admin/audit-trails.tsx`, `apps/api/src/app.ts`, entity `webhooks.tsx` routes |
|
|
| No-code Entity Builder/Code Generator | Sehr grosser Surface-Bereich. Fuer generische Boilerplate vermutlich optional; Core kann nur DB/Admin-Grundlagen behalten. Entity-Metadata-API liegt in `apps/api` unter `/v1/entities/:entity`. | `apps/web/app/routes/admin/entities*`, `apps/web/app/routes/app.$tenant/settings/entities*`, `apps/api/src/app.ts` `/v1/entities/:entity`, `/v1/entities/:entity/rows`, `/v1/entities/:entity/rows/:rowId`, `/v1/relationships/*`, `/v1/exports/:exportJobId/download-url`, `apps/web/app/modules/codeGenerator`, `apps/web/app/modules/formulas`, `apps/web/app/modules/jsonProperties`, `apps/web/app/modules/rows` |
|
|
| AI, Chatbot, Prompt Builder, MCP | Provider-/Kosten-/Security-lastig; klar als Plugin. | `apps/web/app/modules/ai`, `ai-gen`, `chatbot`, `promptBuilder`, `mcp`, `apps/web/app/routes/admin/ai/*`, `apps/web/app/routes/admin/chat/*`, `apps/web/app/routes/app.$tenant/chat/*`, deps `ai`, `@ai-sdk/*`, `@modelcontextprotocol/sdk`, `tokenlens` |
|
|
| Help Desk | Support-Produktflaeche; optional mit KB koppeln. Inbound-Email-Runtime und UI sind entfernt. | `apps/web/app/modules/helpDesk`, `apps/web/app/routes/admin/help-desk*` |
|
|
| Onboarding Builder | Fuer manche SaaS sinnvoll, aber kein minimaler Kern. Optional, zumal eigener Session/Public-Flow existiert. | `apps/web/app/modules/onboarding`, `apps/web/app/routes/admin/onboarding*`, `apps/web/app/routes/onboarding.$id.tsx`, AdminSidebar |
|
|
| Feature Flags | Kann Core fuer grosse Apps sein, aber fuer Boilerplate als Plugin/advanced admin Feature pruefen. | `apps/web/app/modules/featureFlags`, `apps/web/app/routes/admin/feature-flags*`, AdminSidebar |
|
|
| Widgets | Kanonische Feature Decision/S05-Entscheidung D009: `docs/feature-decisions/kb-widgets-workflow-marketing-decision-report.md`, Decision `extract-plugin`. Eingebettete Widgets sind produktnah; alte Widget-Route-/API-Reste sind plugin-disabled und nicht Teil der aktuellen `/v1` API. | `apps/web/app/modules/widgets`, `apps/web/app/routes/app.$tenant/__widgets/*`, `apps/api/src/app.ts`, `packages/db/src/widgets.server.ts`, historische Widget-API-Evidenz |
|
|
| Notifications | Nicht prominent in Sidebar, aber Modul/Routen und externe Provider-Diagnostik sind optional; Produktzustellung laeuft ueber interne Queue/DB-Delivery. | `apps/web/app/modules/notifications`, `apps/web/app/routes/admin/notifications*`, `apps/api/src/app.ts` `/v1/notifications/stream`, `packages/db/src/notifications.server.ts`, `apps/worker/src/handlers.ts` |
|
|
| Storage/Supabase | Wenn File Uploads bleiben, Storage-Abstraktion behalten; Supabase als Provider optional machen. | `apps/web/app/modules/storage`, deps `@supabase/*`, upload/form/media code |
|
|
|
|
## Entfernen pruefen
|
|
|
|
| Feature/Rest | Rationale | Wahrscheinliche Codebereiche |
|
|
| ------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- |
|
|
| Marketing/Public Site Reste | Kanonische Feature Decision/S05-Entscheidung D009: `docs/feature-decisions/kb-widgets-workflow-marketing-decision-report.md`, Decision `remove-from-core`. Marketing ist nicht Teil des Boilerplates; die fruehere public-row-sharing Runtime ist entfernt. | historische D009-Evidenz; deps/Assets fuer landing effects, falls in kuenftigen Scans wieder eingefuehrt |
|
|
| Blog/Changelog Remnants | Kanonische Feature Decision/S05-Entscheidung D009: `docs/feature-decisions/kb-widgets-workflow-marketing-decision-report.md`, Decision `remove-from-core`. Blog/Changelog sind Marketing-/Content-Flaechen und nicht Standard-Boilerplate-Core; die frueheren aktiven Codeflaechen sind bereits geprunt. | historische D009-Evidenz |
|
|
| Affiliate/Rewardful | Planentscheidung: entfernen als Standard. Sichtbare Portal-/Analytics-/Route-Reste, Portal-Schemafelder und die verwaiste App-Icon-Komponente sind entfernt. | historische Migrationen |
|
|
| Provider-Duplikate fuer Mail | Mailjet ist der einzige Runtime-Provider; entfernte Legacy-Provider sind aus Runtime-Code und Env-Katalog entfernt. | `packages/mail`, `apps/web/app/modules/emails` |
|
|
| Playground/Demo/Debug Surfaces | Nicht produktionsreif als Boilerplate-Default; die frueheren Dev-/Debug-/Playground-Routen sind bereits historische Evidenz. | demo site API/routes, falls in kuenftigen Scans wieder eingefuehrt |
|
|
| Marketing Chatbot | Kanonische Feature Decision/S05-Entscheidung D009: `docs/feature-decisions/kb-widgets-workflow-marketing-decision-report.md`, Decision `remove-from-core`. Die unauthenticated Marketing-Chatbot-Flaechen wurden entfernt und bleiben historische Evidenz. | historische D009-Evidenz |
|
|
| Default source-product copy/assets/fake data | Whitelabel-Cleanup im Plan; Fake-Content-Helfer, demo Entity-Row-Route und alte Source-Produkt-Logos sind aus der aktiven Source entfernt. | historische Evidenz |
|
|
| Heavy editor/visual deps nach Feature-Extraktion | Nach Entfernen oder Plugin-Extraktion der owning Features koennen Monaco/Tiptap/Novel/drag-drop/syntax/math deps entfallen; vorher muessen aktive Shared-UI-Imports auditiert werden. Ungenutzte particles deps sind bereits entfernt. | deps unter Review: rich-text editor, drag/drop, syntax highlighting, math rendering |
|
|
|
|
## Bereits entfernt
|
|
|
|
| Feature | Status | Evidenz | Restpruefung |
|
|
| ----------------------------------------------------------------- | ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
| Public `/contact` und `/newsletter` als Default-Marketingflaechen | Entfernt | `BOILERPLATE-PLAN.md` notiert: "Public `/contact` and `/newsletter` were removed as default marketing surfaces." Keine entsprechenden Top-Level-Routen in `apps/web/app/routes` gefunden. | Newsletter-Begriff lebt in Email Marketing/Plan weiter; als Plugin-Grenze oder direkten Mailjet-Flow bewerten. |
|
|
| Affiliate als Standardentscheidung | Entfernt | Plan sagt "remove affiliate/rewardful as standard boilerplate functionality". | Sichtbare Standardfunktion, Portal-Schemafelder und die verwaiste App-Icon-Komponente sind entfernt; nur historische Migrationen enthalten noch alte Spalten. |
|
|
| Monorepo-Skeleton teilweise vorhanden | Review-needed | `apps/*` und `packages/*` package files existieren; Root nutzt `pnpm-lock.yaml`; Details stehen in `docs/architecture-migration-status.md`. | App-Code liegt weiterhin breit unter `apps/web/app/`; Inventar hier bewertet Feature-Surface, nicht Migrationsfortschritt. |
|
|
|
|
## Pruning-Reihenfolge
|
|
|
|
1. Zuerst harte Remove-Entscheidungen umsetzen: Affiliate/Rewardful-Reste, Marketing/Public Site, Blog/Changelog, Demo/Playground.
|
|
2. Danach Plugin-Kandidaten extrahieren oder Product-Core-Module finalisieren: CRM, Email Marketing, KB, Help Desk, Portals/Sites, Widgets.
|
|
3. Dann review-needed Plattformfeatures final klassifizieren: No-code Entity Builder, Workflows, AI/Chatbot/Prompt Builder, Analytics/Metrics, Notifications.
|
|
4. Zum Schluss Dependencies bereinigen, weil viele Libraries nur nach Feature-Entfernung sicher erkennbar ungenutzt sind.
|
|
|
|
## Hinweise fuer Entfernung
|
|
|
|
- Sidebars sind nicht die einzige Wahrheit: einige Features sind nicht sichtbar oder feature-gated, haben aber aktive Routen/API/DB-Code.
|
|
- No-code Entities, Rows, CRM und Email Marketing sind stark gekoppelt. CRM/Email Marketing nicht entfernen, ohne default entity templates und row routes mitzuauditen.
|
|
- App-required public pages nutzen neutrale Core-Layout-Komponenten; PageBlocks/CMS ist kein Core-Feature mehr und wird durch `pnpm run verify:removed-modules` als Runtime-Regression gescannt.
|
|
- Worker/API/Mail-Split laut `BOILERPLATE-PLAN.md` sollte vor grossen Provider-Entfernungen beruecksichtigt werden, damit nicht dieselbe Flaeche zweimal migriert wird.
|