Ctrl K
ComunidadGuías…

CLAUDE.md

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
# DBackup

Self-hosted web app for automating database and file backups with encryption, compression, and retention policies. Built with **Next.js 16 (App Router)**, **TypeScript**, **Prisma** (SQLite), and **Shadcn UI**.

Supported sources include MySQL, PostgreSQL, MongoDB, MariaDB, SQLite, MSSQL, Redis, and Valkey. The adapter lists grow frequently. Never treat a hardcoded adapter list in any doc as exhaustive - run `ls src/lib/adapters/{database,storage,notification}/` for the authoritative list before making claims about supported adapters.

## Guide map

Claude Code loads the nearest `CLAUDE.md` when you touch files in a directory. Read the matching guide before working in that area:

| Working on | Guide |
| :--- | :--- |
| Services, Server Actions, API routes, runner pipeline | [src/CLAUDE.md](src/CLAUDE.md) |
| UI components and the design system | [src/components/CLAUDE.md](src/components/CLAUDE.md) |
| Dashboard pages and the look of the UI redesign | [src/app/dashboard/CLAUDE.md](src/app/dashboard/CLAUDE.md) |
| Database, storage, or notification adapters | [src/lib/adapters/CLAUDE.md](src/lib/adapters/CLAUDE.md) |
| Wiki pages and the changelog | [docs/CLAUDE.md](docs/CLAUDE.md) |
| Marketing website (dbackup.app) | [website/CLAUDE.md](website/CLAUDE.md) |
| Unit and audit tests | [tests/CLAUDE.md](tests/CLAUDE.md) |
| End-to-end tests (Playwright) | [e2e/CLAUDE.md](e2e/CLAUDE.md) |

## Non-negotiable rules

1. **Package manager is `pnpm`.** Never `npm install` or `yarn`. Prisma CLI calls go through `npx prisma ...`.
2. **Never use `console.log` / `console.error` / `console.warn`.** Use the logger from `@/lib/logging/logger`. This holds in Client Components too.
3. **Every change gets a changelog entry** in the same response, written into the fragment of its branch under `changelog/unreleased/`, never into `docs/changelog.md`. AI tooling changes get none. See [Changelog workflow](#changelog-workflow).
4. **Typography**: no em dashes, no semicolons. Use a hyphen where a dash is needed, and end sentences with a period. Applies to code comments, docs, and commit messages.
5. **Language**: all code, comments, and documentation in English.
6. **Never run `prisma migrate dev` while `pnpm dev` is running**, and never use `prisma db push`. See [Prisma migrations](#prisma-migrations).
7. **Every Server Action and API route starts with a permission check.** See [src/CLAUDE.md](src/CLAUDE.md).
8. **Never run `git commit`, `git push`, or `git merge`.** The maintainer commits everything himself. Finish the work, run `pnpm validate`, leave the files in the working tree, and report what changed. This holds even when a plan, a task list, or your own earlier message says "one commit per step" - a plan you wrote is not permission. Never add a `Co-Authored-By` trailer for an AI tool. If a commit was already created by mistake, undo it with `git reset --soft HEAD~1` so the work stays staged, and never force-push to fix it without asking first.
9. **Branches: feature branch, then `dev`, then `main`.** Work happens on a feature branch off `dev`, its pull request goes into `dev`, and a release merges `dev` into `main`. A pull request or a base branch suggested to anyone points at `dev`, never at `main`.

## Architecture (4 layers)

```
src/app/          Route definitions and Server Actions - NO business logic
src/services/     All business logic, organized by domain          <- core
src/lib/adapters/ Plugin system for databases, storage, notifications
src/lib/runner/   Step-based backup execution pipeline
```

Data flows one direction: `page.tsx` (Server Component) fetches through a Service, then passes props to a Client Component. Server Actions are thin wrappers: auth check, Zod validation, service call, revalidate.

A Server Action or API route that contains business logic is a bug. Move it into `src/services/`.

## Commands

```bash
pnpm dev                  # Dev server - auto-applies pending migrations on startup
pnpm run build            # Production build - run before committing
pnpm validate             # Lint + typecheck + unit tests (scripts/validate.sh), no build
pnpm type                 # tsc --noEmit only
pnpm test                 # Unit tests (vitest)
pnpm test:e2e             # End-to-end tests: the image of this checkout beside the dev lab (Playwright)
pnpm lab                  # Menu of the dev lab commands, lab:status shows what runs and what is missing
pnpm lab:up               # Start the dev lab: test DBs, storage servers, notification receivers
pnpm lab:seed             # Fill the dev DB with the first user and every lab connection and job
pnpm lab:check --run      # Test every lab connection and run every lab job once
pnpm run database:reset   # Reset dev DB from scratch via all migrations (lab:reset also seeds it)
pnpm toolbox              # Menu of the release and maintenance commands below, see scripts/toolbox/README.md
pnpm changelog:preview    # Show the changelog block the next release writes from the fragments
pnpm version:bump         # Next version, changelog block and version everywhere, after a CodeQL check of dev
pnpm codeql:check         # CodeQL alerts open on dev that main does not have
pnpm release:tag          # Tag the release on main and push it (release:untag deletes a tag)
```

Docs site and marketing site are separate workspaces: `pnpm docs:dev` (VitePress) and `pnpm website:dev`.

### Prisma migrations

`pnpm dev` runs `prisma migrate deploy` on startup, so the local DB is always current after pulling. No manual step needed.

**Schema changes:**
1. Stop the dev server (Ctrl+C in the node terminal).
2. `npx prisma migrate dev --name <migration-name>`
3. Restart `pnpm dev`.

Running `migrate dev` against a live dev server can trigger an interactive DB reset, which fights the SQLite file lock and crashes the Node process - often taking VS Code with it. `prisma db push` applies schema changes without a migration file, which desyncs `_prisma_migrations` from the real schema and breaks `database:deploy` in production and for other developers.

## Changelog workflow

Every change - feature, bug fix, refactor, docs, CI - gets an entry in the same response. Do not defer it.

**Exception: AI tooling changes never get a changelog entry.** The changelog is published on the docs site for people who run DBackup. Anything that only configures the assistant is invisible to them:

- `CLAUDE.md` files anywhere in the tree
- `.claude/` in full - agents, skills, commands, settings, launch config
- `.gitignore` rules that only exist to track those files

The test is who the line is for. A reader upgrading their instance never needs to know a prompt file changed. Code that ships in the product still counts even when it exists to keep the assistant honest - a lint guard under `tests/` changes the build for every contributor, so it belongs in `### 🧪 Tests`.

**Off `main`, first ask whether the change needs an entry at all.** A fix or behavior change to something already released does. A step in building the unreleased feature the branch exists for does not, and neither does a bug that only ever existed on that branch, because the feature gets one entry rather than one per step. Check it against `git log main..HEAD` instead of assuming: if the code being fixed arrived in one of those commits, nobody has ever run it.

**Every entry is at most two sentences** and stays shallow. Say what the change is, not why it was made, how it works, or what it took to build. Anything needing a third sentence belongs in that feature's guide.

**Inside an entry there is no `;`, no ` - ` and no `- `.** Stricter than the typography rule above, which allows a hyphen as a dash. A sentence reaching for one of them is doing too much work, so split it or cut it. The `- ` opening the line is the list marker and stays.

**Where the entry goes**: into `changelog/unreleased/<branch>.md`, named after the branch with `/` replaced by `-`, never into `docs/changelog.md`. One file per branch, in the Markdown of a version block without the version header and the Docker section, so pull requests that run side by side never touch the same file. A branch that changes its mind edits its own file. `pnpm version:bump` collects the fragments into `docs/changelog.md` at the release and deletes them, a lint guard checks every fragment, and `pnpm changelog:preview` shows the block the next release writes. Format and example: [changelog/unreleased/README.md](changelog/unreleased/README.md).

**Section order** (skip sections with no entries, never reorder):

| # | Change type | Section |
| :--- | :--- | :--- |
| 1 | New feature, adapter, or page | `### ✨ Features` |
| 2 | Bug fix | `### 🐛 Bug Fixes` |
| 3 | Security fix | `### 🔒 Security` |
| 4 | Performance, UX, code quality | `### 🎨 Improvements` |
| 5 | Behavior change (non-breaking) | `### 🔄 Changed` |
| 6 | Deleted feature or code | `### 🗑️ Removed` |
| 7 | New or updated docs article | `### 📝 Documentation` |
| 8 | Test changes | `### 🧪 Tests` |
| 9 | GitHub Actions, Dockerfile, scripts | `### 🔧 CI/CD` |
| 10 | Docker image info (always last, written by the release) | `### 🐳 Docker` |

Entry format and full rules live in [docs/CLAUDE.md](docs/CLAUDE.md).

## File conventions

- **Naming**: `kebab-case` (`backup-service.ts`, `user-table.tsx`).
- **Exports**: named exports preferred, no barrel files in `src/components/`.
- **Path alias**: `@/` maps to `src/`.
- **Max file size**: roughly 300 lines, then split. The runner pipeline in `src/lib/runner/steps/` is the reference for how to split.

## Quick reference

| Concern | Location |
| :--- | :--- |
| DB schema | [prisma/schema.prisma](prisma/schema.prisma) |
| Types and interfaces | [src/lib/core/](src/lib/core/) |
| Permissions | [src/lib/auth/permissions.ts](src/lib/auth/permissions.ts) |
| Access control | [src/lib/auth/access-control.ts](src/lib/auth/access-control.ts) |
| Adapters | [src/lib/adapters/](src/lib/adapters/) |
| Services | [src/services/](src/services/) |
| Server Actions | [src/app/actions/](src/app/actions/) |
| Scheduler (cron) | [src/lib/server/scheduler.ts](src/lib/server/scheduler.ts) |
| Crypto (encrypt/decrypt) | [src/lib/crypto/index.ts](src/lib/crypto/index.ts) |
| Crypto (streams) | [src/lib/crypto/stream.ts](src/lib/crypto/stream.ts) |
| Logger | [src/lib/logging/logger.ts](src/lib/logging/logger.ts) |
| Error classes | [src/lib/logging/errors.ts](src/lib/logging/errors.ts) |
| Shadcn primitives | [src/components/ui/](src/components/ui/) |
| Task colors (tones) | [src/components/ui/tone.ts](src/components/ui/tone.ts), rules under Color in [src/app/dashboard/CLAUDE.md](src/app/dashboard/CLAUDE.md) |
| Dev lab (test DBs, storage, seed) | [lab/](lab/), guide in [docs/developer-guide/reference/dev-lab.md](docs/developer-guide/reference/dev-lab.md) |

## Environment variables

- `ENCRYPTION_KEY` - system key for encrypting secrets at rest. Required.
- `LOG_LEVEL` - `debug` | `info` (default) | `warn` | `error`.
- `SQLITE_WAL_MODE` - `true` (default) | `false`. WAL is on by default for the Prisma SQLite DB. See `src/lib/prisma.ts`.
- `DISABLE_EMAIL_LOGIN` - `true` | `false` (default). Rejects browser email sign-in and sign-up. Server-side `auth.api.*` calls stay open so admin user creation and password resets keep working. See `src/lib/auth/env-flags.ts`.
- `TRUSTED_PROXIES` - the reverse proxies whose `X-Forwarded-For` counts, comma-separated addresses, CIDR ranges and the keywords `private` and `cloudflare`, `none`, or unset for `private`, the loopback and private networks. The custom server resolves the client address in `server/client-address.ts` and passes it in a header of its own, so the app reads `clientAddress()` from `@/lib/core/client-address` and never `X-Forwarded-For` itself. A lint guard checks that.
- `OIDC_AUTO_REDIRECT` - `SsoProvider.providerId` to redirect to instead of rendering the login page. Format checked in `env-validation.ts`, existence in `startup-checks.ts`.