Refactor application module architecture for clarity and explicitness (#18432)

## Summary

- **Module reorganization**: Moved `ApplicationUpgradeService` and cron
jobs to `application-upgrade/`, `ApplicationSyncService` to
`application-manifest/`, and
`runWorkspaceMigration`/`uninstallApplication` mutations to the manifest
resolver — each module now has a single clear responsibility.
- **Explicit install flow**: Removed implicit `ApplicationEntity`
creation from `ApplicationSyncService`. The install service and dev
resolver now explicitly create the `ApplicationEntity` before syncing.
npm packages are resolved at registration time to extract manifest
metadata (universalIdentifier, name, description, etc.), eliminating the
`reconcileUniversalIdentifier` hack.
- **Better error handling**: Frontend hooks now surface actual server
error messages in snackbars instead of swallowing them. Replaced the
ugly `ConfirmationModal` for transfer ownership with a proper form
modal. Fixed `SettingsAdminTableCard` row height overflow and corrected
the `yarn-engine` asset path.

## Test plan
- [ ] Register an npm package — verify manifest metadata (name,
description, universalIdentifier) is extracted correctly
- [ ] Install a registered npm app on a workspace — verify
ApplicationEntity is created and sync succeeds
- [ ] Test `app:dev` CLI flow — verify local app registration and sync
work
- [ ] Upload a tarball — verify registration and install flow
- [ ] Transfer ownership — verify the new modal UX works
- [ ] Verify error messages appear correctly in snackbars when
operations fail


Made with [Cursor](https://cursor.com)
This commit is contained in:
Félix Malfait
2026-03-06 08:45:08 +01:00
committed by GitHub
parent 90cced0e74
commit 514d0017ea
184 changed files with 3179 additions and 1382 deletions
@@ -5,6 +5,7 @@ import { SETTINGS_ADMIN_TABS_ID } from '@/settings/admin-panel/constants/Setting
import { TabList } from '@/ui/layout/tab-list/components/TabList';
import { t } from '@lingui/core/macro';
import {
IconApps,
IconHeart,
IconSettings2,
IconSparkles,
@@ -24,6 +25,12 @@ export const SettingsAdminContent = () => {
Icon: IconSettings2,
disabled: !canAccessFullAdminPanel && !canImpersonate,
},
{
id: SETTINGS_ADMIN_TABS.APPS,
title: t`Apps`,
Icon: IconApps,
disabled: !canAccessFullAdminPanel,
},
{
id: SETTINGS_ADMIN_TABS.AI,
title: t`AI`,
@@ -1,4 +1,5 @@
import { SettingsAdminAI } from '@/settings/admin-panel/ai/components/SettingsAdminAI';
import { SettingsAdminApps } from '@/settings/admin-panel/apps/components/SettingsAdminApps';
import { SettingsAdminGeneral } from '@/settings/admin-panel/components/SettingsAdminGeneral';
import { SettingsAdminConfigVariables } from '@/settings/admin-panel/config-variables/components/SettingsAdminConfigVariables';
import { SETTINGS_ADMIN_TABS } from '@/settings/admin-panel/constants/SettingsAdminTabs';
@@ -16,6 +17,8 @@ export const SettingsAdminTabContent = () => {
switch (activeTabId) {
case SETTINGS_ADMIN_TABS.GENERAL:
return <SettingsAdminGeneral />;
case SETTINGS_ADMIN_TABS.APPS:
return <SettingsAdminApps />;
case SETTINGS_ADMIN_TABS.AI:
return <SettingsAdminAI />;
case SETTINGS_ADMIN_TABS.CONFIG_VARIABLES:
@@ -45,13 +45,13 @@ export const SettingsAdminTableCard = ({
<TableRow
key={index + item.label}
gridAutoColumns={gridAutoColumns}
height={themeCssVariables.spacing[6]}
>
<TableCell
align={labelAlign}
color={themeCssVariables.font.color.tertiary}
height={themeCssVariables.spacing[6]}
height="auto"
gap={themeCssVariables.spacing[2]}
padding={`${themeCssVariables.spacing[2]} ${themeCssVariables.spacing[2]}`}
>
{item.Icon && <item.Icon size={theme.icon.size.md} />}
<span>{item.label}</span>
@@ -59,9 +59,10 @@ export const SettingsAdminTableCard = ({
<TableCell
align={valueAlign}
color={themeCssVariables.font.color.primary}
height={themeCssVariables.spacing[6]}
height="auto"
onClick={item.onClick}
clickable={isDefined(item.onClick)}
padding={`${themeCssVariables.spacing[2]} ${themeCssVariables.spacing[2]}`}
>
{item.value}
</TableCell>