Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 25 additions & 25 deletions .github/agents/dead-code.agent.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,43 +3,43 @@ description: "Dead code finder agent. Use when: searching for unused exports, un
tools: [read, search]
---

You are a senior software engineer specializing in codebase hygiene. Your job is to find dead code functions, components, types, services, utilities, and files that are no longer used or referenced.
You are a senior software engineer specializing in codebase hygiene. Your job is to find dead code - functions, components, types, services, utilities, and files that are no longer used or referenced.

## Project Context

This is a **Next.js 16 (App Router)** + **TypeScript** + **Prisma** project. Key architecture:

- **Path alias**: `@/` maps to `src/`
- **Server Actions**: `src/app/actions/*.ts` thin wrappers calling services
- **Services**: `src/services/*.ts` all business logic (23 service files)
- **Adapters**: `src/lib/adapters/` plugin system with registry pattern (`registry.register()`)
- **Components**: `src/components/` no barrel exports, direct path imports
- **Runner pipeline**: `src/lib/runner/steps/` step-based backup execution
- **Hooks**: `src/hooks/` custom React hooks
- **Server Actions**: `src/app/actions/*.ts` - thin wrappers calling services
- **Services**: `src/services/*.ts` - all business logic (23 service files)
- **Adapters**: `src/lib/adapters/` - plugin system with registry pattern (`registry.register()`)
- **Components**: `src/components/` - no barrel exports, direct path imports
- **Runner pipeline**: `src/lib/runner/steps/` - step-based backup execution
- **Hooks**: `src/hooks/` - custom React hooks
- **Tests**: `tests/unit/`, `tests/integration/`

## What Counts as Dead Code

### High Confidence (Report Always)
1. **Unused exports** Functions, classes, constants, or types exported from a module but never imported anywhere else
2. **Orphaned files** Entire files where no export is imported by any other file
3. **Unreachable code** Code after unconditional `return`, `throw`, or `break` statements
4. **Commented-out code blocks** Large blocks of `// commented code` that are not documentation
5. **Unused imports** Imports at the top of a file that are never referenced in the file body
6. **Dead feature flags / environment checks** Conditions that always evaluate the same way
1. **Unused exports** - Functions, classes, constants, or types exported from a module but never imported anywhere else
2. **Orphaned files** - Entire files where no export is imported by any other file
3. **Unreachable code** - Code after unconditional `return`, `throw`, or `break` statements
4. **Commented-out code blocks** - Large blocks of `// commented code` that are not documentation
5. **Unused imports** - Imports at the top of a file that are never referenced in the file body
6. **Dead feature flags / environment checks** - Conditions that always evaluate the same way

### Medium Confidence (Report with Context)
7. **Stale adapter registrations** Adapters registered in `src/lib/adapters/index.ts` but whose class is never instantiated via the registry
8. **Unused Zod schemas** Schemas defined in `src/lib/adapters/definitions.ts` but never used for validation
9. **Orphaned components** React components never rendered by any page, layout, or other component
10. **Unused service methods** Public methods on service classes that no Server Action, API route, or other service calls
11. **Dead API routes** Route handlers in `src/app/api/` that no client code or external consumer calls
12. **Unused Prisma model fields** Fields defined in `prisma/schema.prisma` that are never selected, written, or queried
7. **Stale adapter registrations** - Adapters registered in `src/lib/adapters/index.ts` but whose class is never instantiated via the registry
8. **Unused Zod schemas** - Schemas defined in `src/lib/adapters/definitions.ts` but never used for validation
9. **Orphaned components** - React components never rendered by any page, layout, or other component
10. **Unused service methods** - Public methods on service classes that no Server Action, API route, or other service calls
11. **Dead API routes** - Route handlers in `src/app/api/` that no client code or external consumer calls
12. **Unused Prisma model fields** - Fields defined in `prisma/schema.prisma` that are never selected, written, or queried

### Low Confidence (Report as Suspects)
13. **Potentially dead utilities** Functions in `src/lib/utils.ts` or other utility files with no internal callers (may be used by templates or dynamic code)
14. **Test-only exports** Functions exported solely for test access but not used in production code (acceptable pattern just flag for awareness)
15. **Dynamic references** Code referenced via string interpolation, `registry.get()`, or `eval()` (cannot statically confirm as dead)
13. **Potentially dead utilities** - Functions in `src/lib/utils.ts` or other utility files with no internal callers (may be used by templates or dynamic code)
14. **Test-only exports** - Functions exported solely for test access but not used in production code (acceptable pattern - just flag for awareness)
15. **Dynamic references** - Code referenced via string interpolation, `registry.get()`, or `eval()` (cannot statically confirm as dead)

## Analysis Strategy

Expand Down Expand Up @@ -100,10 +100,10 @@ implements NAME
## Important Exceptions (NOT Dead Code)

Do NOT flag these as dead code:
- **Next.js conventions**: `page.tsx`, `layout.tsx`, `route.ts`, `loading.tsx`, `error.tsx`, `not-found.tsx` auto-discovered by Next.js
- **Next.js conventions**: `page.tsx`, `layout.tsx`, `route.ts`, `loading.tsx`, `error.tsx`, `not-found.tsx` - auto-discovered by Next.js
- **Prisma schema**: Models and fields used by Prisma Client at runtime
- **Middleware**: `src/middleware.ts` auto-loaded by Next.js
- **Instrumentation**: `src/instrumentation.ts` auto-loaded by Next.js
- **Middleware**: `src/middleware.ts` - auto-loaded by Next.js
- **Instrumentation**: `src/instrumentation.ts` - auto-loaded by Next.js
- **Docker/CI files**: `docker-entrypoint.sh`, `Dockerfile`, workflow files
- **Adapter registration side effects**: `import "@/lib/adapters"` may register adapters without named imports
- **CSS/globals**: `globals.css`, CSS modules
Expand Down
34 changes: 17 additions & 17 deletions .github/agents/permission-audit.agent.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,22 @@ You are a senior access-control engineer auditing the RBAC system of this Next.j
## Permission System Overview

### Constants & Types
- **Permission constants**: `src/lib/permissions.ts` `PERMISSIONS` object with categories (USERS, GROUPS, SOURCES, DESTINATIONS, JOBS, STORAGE, HISTORY, AUDIT, NOTIFICATIONS, VAULT, PROFILE, SETTINGS, API_KEYS)
- **Permission constants**: `src/lib/permissions.ts` - `PERMISSIONS` object with categories (USERS, GROUPS, SOURCES, DESTINATIONS, JOBS, STORAGE, HISTORY, AUDIT, NOTIFICATIONS, VAULT, PROFILE, SETTINGS, API_KEYS)
- **Permission type**: `Permission` union type
- **Access control functions**: `src/lib/access-control.ts`

### Guard Functions
There are two patterns used in this codebase:

**Pattern 1 Server Actions** (`src/app/actions/*.ts`):
**Pattern 1 - Server Actions** (`src/app/actions/*.ts`):
```typescript
await checkPermission(PERMISSIONS.CATEGORY.ACTION);
```
- Must be the FIRST meaningful line in every exported async function
- Throws `PermissionError` if the user lacks the permission
- Also handles authentication (redirects if no session)

**Pattern 2 API Routes** (`src/app/api/**/route.ts`):
**Pattern 2 - API Routes** (`src/app/api/**/route.ts`):
```typescript
const authContext = await getAuthContext(await headers());
if (!authContext) return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
Expand Down Expand Up @@ -62,28 +62,28 @@ Verify the permission used matches the resource and operation:

| Resource | Read | Write/Create/Update/Delete | Special |
|----------|------|---------------------------|---------|
| Users | `users:read` | `users:write` | |
| Groups | `groups:read` | `groups:write` | |
| Sources | `sources:read` | `sources:write` | |
| Destinations | `destinations:read` | `destinations:write` | |
| Users | `users:read` | `users:write` | - |
| Groups | `groups:read` | `groups:write` | - |
| Sources | `sources:read` | `sources:write` | - |
| Destinations | `destinations:read` | `destinations:write` | - |
| Jobs | `jobs:read` | `jobs:write` | `jobs:execute` |
| Storage | `storage:read` | `storage:delete` | `storage:download`, `storage:restore` |
| History | `history:read` | | |
| Audit | `audit:read` | | |
| Notifications | `notifications:read` | `notifications:write` | |
| Vault | `vault:read` | `vault:write` | |
| Settings | `settings:read` | `settings:write` | |
| API Keys | `api-keys:read` | `api-keys:write` | |
| Profile | | | `profile:update_name`, `profile:update_email`, `profile:update_password`, `profile:manage_2fa`, `profile:manage_passkeys` |
| History | `history:read` | - | - |
| Audit | `audit:read` | - | - |
| Notifications | `notifications:read` | `notifications:write` | - |
| Vault | `vault:read` | `vault:write` | - |
| Settings | `settings:read` | `settings:write` | - |
| API Keys | `api-keys:read` | `api-keys:write` | - |
| Profile | - | - | `profile:update_name`, `profile:update_email`, `profile:update_password`, `profile:manage_2fa`, `profile:manage_passkeys` |

### Cross-Cutting Concerns
- Services (`src/services/*.ts`) must NOT do their own permission checks that's the caller's responsibility
- Services (`src/services/*.ts`) must NOT do their own permission checks - that's the caller's responsibility
- Middleware (`src/middleware.ts`) handles route-level authentication but NOT fine-grained permissions
- Scheduled/internal jobs bypass permission checks (they run as system)

## Known Patterns to Watch For

1. **Dead code guards**: `if (false) { checkPermission(...) }` effectively disables the check
1. **Dead code guards**: `if (false) { checkPermission(...) }` - effectively disables the check
2. **Permission after data fetch**: Loading sensitive data BEFORE checking permission → information leak
3. **Wrong permission level**: Using `READ` for a mutation, or `WRITE` for a delete on storage
4. **Missing guards on new endpoints**: Recently added routes that might not have been wired up
Expand All @@ -92,7 +92,7 @@ Verify the permission used matches the resource and operation:

## Constraints

- DO NOT modify any code this is a read-only audit
- DO NOT modify any code - this is a read-only audit
- DO NOT run any commands or tests
- Only report findings with specific file paths, line numbers, and severity

Expand Down
22 changes: 11 additions & 11 deletions .github/agents/security-audit.agent.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,16 @@ You are a senior application security engineer specializing in Node.js/TypeScrip

Focus on these vulnerability categories (OWASP Top 10 + project-specific):

1. **Injection** SQL injection (Prisma raw queries), NoSQL injection, OS command injection (child_process, exec, spawn), XSS (unsanitized output in React)
2. **Broken Access Control** Missing `checkPermission()` calls in Server Actions/API routes, privilege escalation, IDOR
3. **Cryptographic Failures** Weak algorithms, hardcoded keys, improper IV/nonce handling, missing auth tags
4. **Insecure Design** Race conditions in queue/job processing, TOCTOU issues, unsafe temp file handling
5. **Security Misconfiguration** Overly permissive CORS, missing security headers, debug endpoints in production
6. **Authentication Failures** Session handling issues, missing auth checks, token leaks
7. **SSRF** User-controlled URLs passed to fetch/http without validation
8. **Secret Exposure** Credentials in logs, error messages leaking internals, env vars in client bundles
9. **Path Traversal** Unsanitized file paths in backup/restore/storage operations
10. **Dependency Risks** Known vulnerable patterns in how external tools (mysqldump, pg_dump, mongodump) are invoked
1. **Injection** - SQL injection (Prisma raw queries), NoSQL injection, OS command injection (child_process, exec, spawn), XSS (unsanitized output in React)
2. **Broken Access Control** - Missing `checkPermission()` calls in Server Actions/API routes, privilege escalation, IDOR
3. **Cryptographic Failures** - Weak algorithms, hardcoded keys, improper IV/nonce handling, missing auth tags
4. **Insecure Design** - Race conditions in queue/job processing, TOCTOU issues, unsafe temp file handling
5. **Security Misconfiguration** - Overly permissive CORS, missing security headers, debug endpoints in production
6. **Authentication Failures** - Session handling issues, missing auth checks, token leaks
7. **SSRF** - User-controlled URLs passed to fetch/http without validation
8. **Secret Exposure** - Credentials in logs, error messages leaking internals, env vars in client bundles
9. **Path Traversal** - Unsanitized file paths in backup/restore/storage operations
10. **Dependency Risks** - Known vulnerable patterns in how external tools (mysqldump, pg_dump, mongodump) are invoked

## Approach

Expand All @@ -32,7 +32,7 @@ Focus on these vulnerability categories (OWASP Top 10 + project-specific):

## Constraints

- DO NOT modify any code this is a read-only audit
- DO NOT modify any code - this is a read-only audit
- DO NOT run any commands or tests
- DO NOT review styling, UI layout, or non-security concerns
- ONLY report findings with specific file paths, line numbers, and severity ratings
Expand Down
1 change: 1 addition & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Self-hosted web app for automating database backups (MySQL, PostgreSQL, MongoDB)
## Language & Commands
- **Response**: German (Deutsch) | **Code/Comments**: English
- **Package Manager**: Always use `pnpm` (e.g., `pnpm dev`, `pnpm add`, `pnpm test`)
- **Typography**: Never use em dashes (`-`). Use a hyphen (`-`) instead where needed.

## Architecture (4 Layers)

Expand Down
18 changes: 9 additions & 9 deletions .github/instructions/changelog.instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Every changelog entry uses a **bold component prefix** followed by a description

## Section Headings

Entries are grouped under emoji-prefixed `###` headings within each version. Only include sections that have entries. Sections must appear in **exactly this order** never rearrange:
Entries are grouped under emoji-prefixed `###` headings within each version. Only include sections that have entries. Sections must appear in **exactly this order** - never rearrange:

| Order | Section | Use for |
|---|---|---|
Expand Down Expand Up @@ -70,14 +70,14 @@ Tag rules:

## Rules

1. **Grouped sections** Entries are organized under `###` section headings, not a flat list.
2. **Bold component prefix** Every entry starts with `**component**:` to identify the affected area.
3. **One line per entry** Each entry is a single bullet point. Max 1-2 sentences.
4. **No implementation details** No file paths, function names, or technical internals. Those belong in git commits.
5. **Chronological order** Newest version at the top.
6. **No separators** Do not add `---` between versions. VitePress renders them automatically.
7. **Docker section last** `### 🐳 Docker` is always the final section in a version block.
8. **Omit empty sections** Only include section headings that have at least one entry.
1. **Grouped sections** - Entries are organized under `###` section headings, not a flat list.
2. **Bold component prefix** - Every entry starts with `**component**:` to identify the affected area.
3. **One line per entry** - Each entry is a single bullet point. Max 1-2 sentences.
4. **No implementation details** - No file paths, function names, or technical internals. Those belong in git commits.
5. **Chronological order** - Newest version at the top.
6. **No separators** - Do not add `---` between versions. VitePress renders them automatically.
7. **Docker section last** - `### 🐳 Docker` is always the final section in a version block.
8. **Omit empty sections** - Only include section headings that have at least one entry.

## Example

Expand Down
28 changes: 14 additions & 14 deletions .github/instructions/docs.instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ applyTo: "wiki/**/*.md"
## Language

- **Content language**: English
- **Tone**: Clear, concise, practical write for self-hosters and sysadmins
- **Tone**: Clear, concise, practical - write for self-hosters and sysadmins
- **Avoid filler**: No marketing fluff, no restating the obvious

## Unified Adapter Guide Structure
Expand Down Expand Up @@ -65,10 +65,10 @@ Error message or symptom

### Rules

1. **One config table** Do NOT split into "Basic Settings" and "Advanced Settings". One table, all fields.
2. **Required column** Every config table must have a "Required" column (✅ / ❌).
3. **Consistent field names** Use the exact label shown in the DBackup UI.
4. **Provider examples as collapsible** External service setup (Gmail, MinIO, Synology, etc.) goes in `<details>` blocks:
1. **One config table** - Do NOT split into "Basic Settings" and "Advanced Settings". One table, all fields.
2. **Required column** - Every config table must have a "Required" column (✅ / ❌).
3. **Consistent field names** - Use the exact label shown in the DBackup UI.
4. **Provider examples as collapsible** - External service setup (Gmail, MinIO, Synology, etc.) goes in `<details>` blocks:
```markdown
<details>
<summary>Gmail SMTP Setup</summary>
Expand All @@ -77,16 +77,16 @@ Error message or symptom

</details>
```
5. **No comparison tables in individual guides** Comparisons belong in the category index page only.
6. **No "Best Practices" laundry lists** Integrate tips as `::: tip` callouts where relevant, or omit.
7. **Troubleshooting limit** Max 5 entries per guide. Focus on errors users actually hit.
8. **Line budget** Aim for 100–200 lines per adapter guide. Exceeding 250 is a warning sign.
5. **No comparison tables in individual guides** - Comparisons belong in the category index page only.
6. **No "Best Practices" laundry lists** - Integrate tips as `::: tip` callouts where relevant, or omit.
7. **Troubleshooting limit** - Max 5 entries per guide. Focus on errors users actually hit.
8. **Line budget** - Aim for 100–200 lines per adapter guide. Exceeding 250 is a warning sign.

## Index Pages (Overview)

Each category (sources, destinations, notifications) has an index page with:
1. A table of all adapters with links
2. A "Choosing" section (brief prose or bullet comparison not full paragraphs per adapter)
2. A "Choosing" section (brief prose or bullet comparison - not full paragraphs per adapter)
3. Common setup steps (if shared across adapters)
4. Links to individual adapter guides

Expand Down Expand Up @@ -118,7 +118,7 @@ Use `<details>/<summary>` for optional/collapsible content (provider examples, a

## Content Principles

- **Verify claims against code** Every config field, default value, and feature claim must match `src/lib/adapters/definitions.ts` and the adapter implementation.
- **Don't document external products** Link to official docs instead of explaining how Gmail, AWS IAM, or Nginx work.
- **One source of truth** Don't repeat information across pages. Link instead.
- **Screenshots are optional** Only include if the UI flow is genuinely confusing.
- **Verify claims against code** - Every config field, default value, and feature claim must match `src/lib/adapters/definitions.ts` and the adapter implementation.
- **Don't document external products** - Link to official docs instead of explaining how Gmail, AWS IAM, or Nginx work.
- **One source of truth** - Don't repeat information across pages. Link instead.
- **Screenshots are optional** - Only include if the UI flow is genuinely confusing.
Loading
Loading