npm package: @nextlevels/crud
Description: **CRUD Factory Package** - Generiere komplette CRUD-Operationen in wenigen Zeilen! 🚀
Latest version: 0.0.2

# @nextlevels/crud

**CRUD Factory Package** - Generiere komplette CRUD-Operationen in wenigen Zeilen! 🚀

## Features

✅ **Auto-generierte tRPC Router** mit allen CRUD-Operationen
✅ **Auto-generierte DataTable Columns** mit Actions
✅ **Auto-generierte List Pages** mit Pagination & Sorting
✅ **Type-Safe** - Vollständige TypeScript-Unterstützung
✅ **DRY** - Kein duplizierter Code mehr!
✅ **Flexible** - Einfach anzupassen und zu erweitern

---

## Quick Start

### 1. Entity Config erstellen

```typescript
import { Role } from "@prisma/client";
import mySchema from "@/schema/my-schema";

const entityConfig = {
  name: "myEntity",
  schema: mySchema,
  permissions: [Role.ADMIN, Role.SUPERADMIN],
  labels: {
    singular: "Mein Entity",
    plural: "Meine Entities",
    description: "Verwalte alle Entities",
  },
};
```

### 2. Router erstellen (1 Zeile!)

```typescript
import { createEntityRouter } from "@nextlevels/crud/router";
import {
  createTRPCRouter,
  protectedProcedure,
  publicProcedure,
} from "@/server/api/trpc";

export const myEntityRouter = createTRPCRouter(
  createEntityRouter(entityConfig, { publicProcedure, protectedProcedure })
);
```

**Das war's!** Du hast jetzt:

- `fetchAll` - Alle Entities abrufen (public)
- `fetchPaginated` - Paginierte Liste (protected)
- `fetchById` - Einzelnes Entity (protected)
- `create` - Neues Entity erstellen (protected)
- `update` - Entity bearbeiten (protected)
- `delete` - Entity löschen (protected)

### 3. Columns erstellen

```typescript
import { createEntityColumns } from "@nextlevels/crud/columns";

export function getColumns({ isLoading, onSuccess } = {}) {
  const deleteMutation = api.myEntity.delete;

  return createEntityColumns({
    entityName: "myEntity",
    singularLabel: "Mein Entity",
    basePath: "/admin/my-entities",
    deleteMutation,
    isLoading,
    onSuccess,
    columns: [
      { key: "name", label: "Name", sortable: true },
      {
        key: "status",
        label: "Status",
        render: (value) => (value ? "Aktiv" : "Inaktiv"),
      },
    ],
  });
}
```

### 4. List Page erstellen

```typescript
import { createListPage } from "@nextlevels/crud/pages";

const MyEntityListPage = createListPage({
  pluralLabel: "Meine Entities",
  singularLabel: "Mein Entity",
  description: "Verwalte alle Entities hier.",
  basePath: "/admin/my-entities",
  useQuery: api.myEntity.fetchPaginated.useQuery,
  columns: getColumns(),
});

export default MyEntityListPage;
```

---

## API Reference

### `createEntityRouter(config, builder)`

Erstellt einen vollständigen tRPC Router mit CRUD-Operationen.

**Parameter:**

- `config: EntityConfig` - Entity-Konfiguration
- `builder: { publicProcedure, protectedProcedure }` - tRPC Builder

**Returns:** Router mit folgenden Endpoints:

- `fetchAll(input?)` - Alle Entities (limit, where)
- `fetchPaginated(input)` - Paginierte Liste
- `fetchById(input)` - Einzelnes Entity
- `create(input)` - Neues Entity
- `update(input)` - Entity bearbeiten
- `delete(input)` - Entity löschen

### `createEntityColumns(options)`

Erstellt DataTable Columns mit Actions.

**Parameter:**

- `entityName: string` - Entity-Name
- `singularLabel: string` - Singular-Label
- `basePath: string` - Basis-Pfad (z.B. `/admin/videos`)
- `columns: ColumnConfig[]` - Column-Definitionen
- `deleteMutation` - tRPC Delete Mutation
- `isLoading?: boolean` - Loading-State
- `onSuccess?: () => void` - Success-Callback
- `displayField?: string` - Feld für Delete-Bestätigung (default: "name")

**ColumnConfig:**

```typescript
{
  key: string;              // Feld-Name
  label: string;            // Column-Header
  sortable?: boolean;       // Sortierbar? (default: true)
  render?: (value) => any;  // Custom Renderer
  accessor?: (item) => any; // Custom Accessor
}
```

### `createListPage(options)`

Erstellt eine List-Page Component.

**Parameter:**

- `pluralLabel: string` - Plural-Label
- `singularLabel: string` - Singular-Label
- `description?: string` - Beschreibung
- `basePath: string` - Basis-Pfad
- `useQuery` - tRPC Query Hook
- `columns: ColumnDef[]` - Table Columns
- `initialPageSize?: number` - Initiale Page-Size (default: 10)

---

## Vergleich: Vorher vs. Nachher

### Router

**Vorher:** 237 Zeilen Code pro Entity
**Nachher:** ~15 Zeilen Code

```typescript
// Vorher: video.ts (237 Zeilen)
export const videoRouter = createTRPCRouter({
  fetchAll: publicProcedure.input(...).query(async ({ ctx, input }) => {
    // 25 Zeilen
  }),
  fetchPaginated: protectedProcedure.input(...).query(async ({ input, ctx }) => {
    // 50 Zeilen
  }),
  // ... +160 Zeilen mehr
});

// Nachher: video-new.ts (15 Zeilen)
const videoConfig = { ... };
export const videoRouter = createTRPCRouter(
  createEntityRouter(videoConfig, { publicProcedure, protectedProcedure })
);
```

### Columns

**Vorher:** 148 Zeilen Code pro Entity
**Nachher:** ~20 Zeilen Code

### List Page

**Vorher:** 73 Zeilen Code pro Entity
**Nachher:** ~15 Zeilen Code

---

## Advanced Usage

### Custom Permissions Check

```typescript
const config = {
  name: "myEntity",
  schema: mySchema,
  permissions: [Role.ADMIN, Role.SUPERADMIN],
  // ...
};
```

### Custom Default Sort

```typescript
const config = {
  name: "myEntity",
  schema: mySchema,
  defaultSort: {
    field: "createdAt",
    order: "desc",
  },
  // ...
};
```

### Custom Prisma Model Name

```typescript
const config = {
  name: "tire",
  prismaModel: "Tire", // Falls anders als Entity-Name
  // ...
};
```

### Custom Column Renderer

```typescript
columns: [
  {
    key: "status",
    label: "Status",
    render: (value) => (
      <Badge variant={value ? "success" : "destructive"}>
        {value ? "Aktiv" : "Inaktiv"}
      </Badge>
    ),
  },
];
```

---

## Migration Guide

So migrierst du bestehende Entities:

1. **Router migrieren:**

   - Alte Router-Datei kopieren
   - Entity Config erstellen
   - `createEntityRouter` verwenden
   - Alte Datei löschen

2. **Columns migrieren:**

   - Bestehende Columns analysieren
   - `ColumnConfig` Array erstellen
   - `createEntityColumns` verwenden

3. **Pages migrieren:**
   - `createListPage` verwenden
   - Columns importieren
   - Alte Page-Datei löschen

---

## Next Steps

- [ ] Erstelle Generator-CLI für neue Entities
- [ ] Füge Form-Page Factory hinzu
- [ ] Erweitere um Bulk-Actions
- [ ] Füge Export-Funktionen hinzu

---

## License

Private Package - Part of CMS Template Monorepo