Replace all marketing placeholder content with real MYeasyCMS content
Some checks failed
Workflow / ʦ TypeScript (push) Failing after 6m12s
Workflow / ⚫️ Test (push) Has been skipped

- Logo: Replace generic Makerkit SVG with MYeasyCMS branded logo (grid icon + styled text)
- Blog: Replace 3 SaaS placeholder posts with 5 real articles (Vereinsverwaltung, SEPA, Website, DSGVO, Mitglieder-Tipps)
- Changelog: Replace 6 generic entries with real feature announcements (Verbandsverwaltung, Fischerei, Dateien, Kurse, Einladungen, i18n)
- Documentation: Rewrite all 20 docs from Makerkit references to MYeasyCMS content
- FAQ: Replace 6 generic SaaS questions with 10 real MYeasyCMS questions
- Navigation: Replace Changelog link with Contact in main nav
- Footer: Reorganize into Product/Company/Legal sections
- Translations: Update all EN marketing strings to match real Com.BISS content
This commit is contained in:
Zaid Marzguioui
2026-04-01 21:09:06 +02:00
parent bbb33aa63d
commit a5bbf42901
49 changed files with 1320 additions and 4735 deletions

View File

@@ -1,430 +1,34 @@
---
title: "Querying Data"
description: "Learn how to query and filter data from your database."
title: "Datenexport"
description: "Exportieren Sie Ihre Vereinsdaten in verschiedenen Formaten — für Berichte, Auswertungen und Datensicherung."
publishedAt: 2024-04-11
order: 3
order: 1
status: "published"
---
> **Note:** This is mock/placeholder content for demonstration purposes.
MYeasyCMS bietet umfangreiche Exportmöglichkeiten für alle Ihre Vereinsdaten.
Efficiently query and filter data using Supabase's query builder.
## Exportformate
## Basic Queries
- **Excel (.xlsx)** — Für die Weiterverarbeitung in Tabellenkalkulationen
- **CSV** — Universelles Format für den Datenaustausch
- **PDF** — Für druckfertige Berichte und Dokumente
- **SEPA XML (pain.008)** — Für den Bankeinzug per Lastschrift
### Select All
## Was kann exportiert werden?
```typescript
const { data, error } = await client
.from('projects')
.select('*');
```
### Mitgliederdaten
Exportieren Sie die vollständige Mitgliederliste oder gefilterte Teilmengen — nach Abteilung, Status, Eintrittsdatum oder anderen Kriterien.
### Select Specific Columns
### Finanzdaten
Beitragsübersichten, offene Posten, Zahlungshistorie und SEPA-Dateien für den Bankeinzug.
```typescript
const { data, error } = await client
.from('projects')
.select('id, name, created_at');
```
### Kurs- und Veranstaltungsdaten
Teilnehmerlisten, Kursübersichten und Anwesenheitslisten.
### Select with Related Data
### Dokumente
Generierte Dokumente (Ausweise, Rechnungen, Briefe) als PDF herunterladen.
```typescript
const { data, error } = await client
.from('projects')
.select(`
id,
name,
account:accounts(id, name),
tasks(id, title, completed)
`);
```
## Datensicherung
## Filtering
### Equal
```typescript
const { data } = await client
.from('projects')
.select('*')
.eq('status', 'active');
```
### Not Equal
```typescript
const { data } = await client
.from('projects')
.select('*')
.neq('status', 'deleted');
```
### Greater Than / Less Than
```typescript
const { data } = await client
.from('projects')
.select('*')
.gt('created_at', '2024-01-01')
.lt('budget', 10000);
```
### In Array
```typescript
const { data } = await client
.from('projects')
.select('*')
.in('status', ['active', 'pending']);
```
### Like (Pattern Matching)
```typescript
const { data } = await client
.from('projects')
.select('*')
.like('name', '%website%');
```
### Full-Text Search
```typescript
const { data } = await client
.from('projects')
.select('*')
.textSearch('description', 'design & development');
```
## Ordering
### Order By
```typescript
const { data } = await client
.from('projects')
.select('*')
.order('created_at', { ascending: false });
```
### Multiple Order By
```typescript
const { data } = await client
.from('projects')
.select('*')
.order('status')
.order('created_at', { ascending: false });
```
## Pagination
### Limit
```typescript
const { data } = await client
.from('projects')
.select('*')
.limit(10);
```
### Range (Offset)
```typescript
const page = 2;
const pageSize = 10;
const from = (page - 1) * pageSize;
const to = from + pageSize - 1;
const { data, count } = await client
.from('projects')
.select('*', { count: 'exact' })
.range(from, to);
```
## Aggregations
### Count
```typescript
const { count } = await client
.from('projects')
.select('*', { count: 'exact', head: true });
```
### Count with Filters
```typescript
const { count } = await client
.from('projects')
.select('*', { count: 'exact', head: true })
.eq('status', 'active');
```
## Advanced Queries
### Multiple Filters
```typescript
const { data } = await client
.from('projects')
.select('*')
.eq('account_id', accountId)
.eq('status', 'active')
.gte('created_at', startDate)
.lte('created_at', endDate)
.order('created_at', { ascending: false })
.limit(20);
```
### OR Conditions
```typescript
const { data } = await client
.from('projects')
.select('*')
.or('status.eq.active,status.eq.pending');
```
### Nested OR
```typescript
const { data } = await client
.from('projects')
.select('*')
.or('and(status.eq.active,priority.eq.high),status.eq.urgent');
```
## Joins
### Inner Join
```typescript
const { data } = await client
.from('projects')
.select(`
*,
account:accounts!inner(
id,
name
)
`)
.eq('account.name', 'Acme Corp');
```
### Left Join
```typescript
const { data } = await client
.from('projects')
.select(`
*,
tasks(*)
`);
```
## Null Handling
### Is Null
```typescript
const { data } = await client
.from('projects')
.select('*')
.is('completed_at', null);
```
### Not Null
```typescript
const { data} = await client
.from('projects')
.select('*')
.not('completed_at', 'is', null);
```
## Insert Data
### Single Insert
```typescript
const { data, error } = await client
.from('projects')
.insert({
name: 'New Project',
account_id: accountId,
status: 'active',
})
.select()
.single();
```
### Multiple Insert
```typescript
const { data, error } = await client
.from('projects')
.insert([
{ name: 'Project 1', account_id: accountId },
{ name: 'Project 2', account_id: accountId },
])
.select();
```
## Update Data
### Update with Filter
```typescript
const { data, error } = await client
.from('projects')
.update({ status: 'completed' })
.eq('id', projectId)
.select()
.single();
```
### Update Multiple Rows
```typescript
const { data, error } = await client
.from('projects')
.update({ status: 'archived' })
.eq('account_id', accountId)
.lt('updated_at', oldDate);
```
## Delete Data
### Delete with Filter
```typescript
const { error } = await client
.from('projects')
.delete()
.eq('id', projectId);
```
### Delete Multiple
```typescript
const { error } = await client
.from('projects')
.delete()
.in('id', projectIds);
```
## Upsert
### Insert or Update
```typescript
const { data, error } = await client
.from('projects')
.upsert({
id: projectId,
name: 'Updated Name',
status: 'active',
})
.select()
.single();
```
## RPC (Stored Procedures)
### Call Database Function
```typescript
const { data, error } = await client
.rpc('get_user_projects', {
user_id: userId,
});
```
### With Complex Parameters
```typescript
const { data, error } = await client
.rpc('search_projects', {
search_term: 'design',
account_ids: [1, 2, 3],
min_budget: 5000,
});
```
## Error Handling
### Basic Error Handling
```typescript
const { data, error } = await client
.from('projects')
.select('*');
if (error) {
console.error('Error fetching projects:', error.message);
throw error;
}
return data;
```
### Typed Error Handling
```typescript
import { PostgrestError } from '@supabase/supabase-js';
function handleDatabaseError(error: PostgrestError) {
switch (error.code) {
case '23505': // unique_violation
throw new Error('A project with this name already exists');
case '23503': // foreign_key_violation
throw new Error('Invalid account reference');
default:
throw new Error('Database error: ' + error.message);
}
}
```
## TypeScript Types
### Generated Types
```typescript
import { Database } from '~/types/database.types';
type Project = Database['public']['Tables']['projects']['Row'];
type ProjectInsert = Database['public']['Tables']['projects']['Insert'];
type ProjectUpdate = Database['public']['Tables']['projects']['Update'];
```
### Typed Queries
```typescript
const { data } = await client
.from('projects')
.select('*')
.returns<Project[]>();
```
## Performance Tips
1. **Select only needed columns** - Don't use `select('*')` unnecessarily
2. **Use indexes** - Create indexes on frequently filtered columns
3. **Limit results** - Always paginate large datasets
4. **Avoid N+1 queries** - Use joins instead of multiple queries
5. **Use RPC for complex queries** - Move logic to database
6. **Cache when possible** - Use React Query or similar
7. **Profile queries** - Use `EXPLAIN ANALYZE` in SQL
## Best Practices
1. **Always handle errors** - Check error responses
2. **Validate input** - Use Zod or similar
3. **Use TypeScript** - Generate and use types
4. **Consistent naming** - Follow database naming conventions
5. **Document complex queries** - Add comments
6. **Test queries** - Unit test database operations
7. **Monitor performance** - Track slow queries
Für die eigene Datensicherung können Sie regelmäßig einen Gesamtexport Ihrer Mitgliederdaten erstellen. Dies dient als zusätzliche Sicherheit neben den automatischen Server-Backups.