feat(phase2): phase 6 - integration & polish

Fix all build/type/lint errors, write 60 new tests (175 total),
update seed with new widget types and team board permissions,
install missing svelte-i18n dependency, fix DynamicIcon for Svelte 5.
This commit is contained in:
2026-03-24 23:43:31 +03:00
parent 5bb4fbcedf
commit 87ed928a3a
17 changed files with 2057 additions and 59 deletions
+122 -2
View File
@@ -254,7 +254,11 @@ async function main() {
'widget-homeassistant',
'widget-grafana',
'widget-portainer',
'widget-pihole'
'widget-pihole',
'widget-bookmark-docs',
'widget-note-welcome',
'widget-embed-grafana',
'widget-status-infra'
];
await prisma.widget.deleteMany({ where: { id: { in: seedWidgetIds } } });
@@ -338,7 +342,123 @@ async function main() {
}
});
console.log(' Created widgets for all apps');
// --- Bookmark widget ---
await prisma.widget.create({
data: {
id: 'widget-bookmark-docs',
sectionId: mediaSection.id,
type: 'bookmark',
order: 1,
config: JSON.stringify({
url: 'https://docs.selfhosted.example.com',
label: 'Self-Hosted Docs',
icon: 'book-open',
description: 'Documentation for all self-hosted services'
})
}
});
// --- Note widget ---
await prisma.widget.create({
data: {
id: 'widget-note-welcome',
sectionId: mediaSection.id,
type: 'note',
order: 2,
config: JSON.stringify({
content: '# Welcome\n\nThis is your **home dashboard**. Use sections to organize apps, bookmarks, notes, and more.\n\n- Drag to reorder\n- Click to launch\n- Edit to customize',
format: 'markdown'
})
}
});
// --- Embed widget ---
await prisma.widget.create({
data: {
id: 'widget-embed-grafana',
sectionId: infraSection.id,
type: 'embed',
order: 5,
config: JSON.stringify({
url: 'http://grafana.local:3000/d/server-stats/overview?orgId=1&kiosk',
height: 400
})
}
});
// --- Status widget ---
await prisma.widget.create({
data: {
id: 'widget-status-infra',
sectionId: networkSection.id,
type: 'status',
order: 1,
config: JSON.stringify({
appIds: [createdApps[4].id, createdApps[5].id, createdApps[6].id],
label: 'Infrastructure Status'
})
}
});
console.log(' Created widgets for all apps (including bookmark, note, embed, status)');
// --- Second Board with permissions ---
const teamBoard = await prisma.board.upsert({
where: { id: 'team-board' },
update: {},
create: {
id: 'team-board',
name: 'Team Board',
icon: 'users',
description: 'A board with permission controls for the team',
isDefault: false,
isGuestAccessible: false,
createdById: admin.id
}
});
console.log(' Created board:', teamBoard.name);
// Grant 'view' permission to the regular user on the team board
await prisma.permission.upsert({
where: {
entityType_entityId_targetType_targetId: {
entityType: 'board',
entityId: teamBoard.id,
targetType: 'user',
targetId: regularUser.id
}
},
update: { level: 'view' },
create: {
entityType: 'board',
entityId: teamBoard.id,
targetType: 'user',
targetId: regularUser.id,
level: 'view'
}
});
// Grant 'edit' permission to the 'user' group on the team board
await prisma.permission.upsert({
where: {
entityType_entityId_targetType_targetId: {
entityType: 'board',
entityId: teamBoard.id,
targetType: 'group',
targetId: userGroup.id
}
},
update: { level: 'edit' },
create: {
entityType: 'board',
entityId: teamBoard.id,
targetType: 'group',
targetId: userGroup.id,
level: 'edit'
}
});
console.log(' Set permissions on team board');
console.log('Seeding complete!');
}