9c518238f5
Neues Modell Dashboard (D-01/D-02/D-09): position statt Standard-Feld, kein Unique auf (userId, position) - Umsortieren schreibt spaeter alle Positionen einer Transaktion neu. WidgetInstance/DashboardLayout haengen jetzt am Reiter statt am Benutzer (DashboardLayout.dashboardId @unique ersetzt userId @unique). Migration 20260923120000_dashboard_tabs: Zeilenschutz mit Mandant- UND Benutzerdimension (Form 20260911120000/20260921120000), Bestands- uebernahme fuer jeden Benutzer mit Kacheln oder Anordnung VOR den Fremdschluesseln (D-03) - gemessen: 0 Kacheln/Anordnungen ohne Reiter, genau 2 Reiter auf Position 0. dashboard.service.ts: listDashboards() (Transaktionssperre gegen doppelte Erstanlage, T-AD9-07), Riegel assertOwnedDashboard() (fail- closed gegen fremde Reiter, T-AD9-01/02/03) - getLayout/saveLayout/ getWidgets/addWidget laufen jetzt ueber dashboardId statt userId. GET /dashboard/tabs neu; die vier bestehenden Wege reichen die Reiter- Kennung durch. Verhalten fuer den Benutzer unveraendert (ein Reiter, wie bisher) - Task 2 ergaenzt Anlegen/Umbenennen/Loeschen/Umsortieren. dashboard.service.spec.ts: 43 Tests (31 alte unveraendert + 12 neue fuer Reiter-Anlage, -Reihenfolge und den Fremdreiter-Riegel bei allen vier Wegen). Zugriffsklassifikation nachgerechnet: 75 Paare (+1), Bereich dashboard 21->24 gebunden. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
30 lines
911 B
TypeScript
30 lines
911 B
TypeScript
import { IsIn, IsObject, IsOptional, IsString } from 'class-validator';
|
|
import { WIDGET_TYPES } from '@tessera/shared';
|
|
|
|
/**
|
|
* DTO for creating a new widget instance on one dashboard tab.
|
|
*
|
|
* quick-260922-m1h: `widgetType` wird gegen `WIDGET_TYPES` aus
|
|
* `@tessera/shared` geprüft — dieselbe Liste, aus der das Frontend seine
|
|
* Registry und seinen Katalog ableitet. Vorher stand die Liste hier ein
|
|
* zweites Mal; vergaß man einen Eintrag, lehnte die API eine im Katalog
|
|
* angebotene Kachel mit 400 ab.
|
|
*
|
|
* quick-260923-ad9: `dashboardId` selects the tab — the service verifies
|
|
* ownership before writing (`assertOwnedDashboard`).
|
|
*
|
|
* config is optional and defaults to {} on the model.
|
|
*/
|
|
export class CreateWidgetDto {
|
|
@IsString()
|
|
dashboardId!: string;
|
|
|
|
@IsString()
|
|
@IsIn([...WIDGET_TYPES])
|
|
widgetType!: string;
|
|
|
|
@IsOptional()
|
|
@IsObject()
|
|
config?: Record<string, unknown>;
|
|
}
|