diff --git a/.claude/skills/wiki-db-migration/SKILL.md b/.claude/skills/wiki-db-migration/SKILL.md new file mode 100644 index 00000000..efcc77bf --- /dev/null +++ b/.claude/skills/wiki-db-migration/SKILL.md @@ -0,0 +1,69 @@ +--- +name: wiki-db-migration +description: Use when adding, modifying, or rolling back database migrations in this Wiki.js repo (Knex + Objection.js) +--- + +# Database Migrations + +Wiki.js uses Knex for migrations and Objection.js as the ORM on top. Migrations are in `server/db/migrations/`. + +**Stop and ask the user before touching migrations.** They are irreversible once run against a real DB. + +## Creating a Migration + +```bash +# From repo root — uses knex CLI via node_modules +node_modules/.bin/knex migrate:make --knexfile server/db/knex.js +``` + +New file created at `server/db/migrations/_.js`. + +## Migration File Structure + +```js +exports.up = async (knex) => { + // additive: create table, add column, add index + await knex.schema.table('pages', t => { + t.string('newColumn').defaultTo('') + }) +} + +exports.down = async (knex) => { + // reverse of up — always implement down + await knex.schema.table('pages', t => { + t.dropColumn('newColumn') + }) +} +``` + +## Running Migrations + +Wiki.js runs `knex.migrate.latest()` automatically on server start. No manual run needed in dev. + +To run manually: +```bash +node_modules/.bin/knex migrate:latest --knexfile server/db/knex.js +node_modules/.bin/knex migrate:rollback --knexfile server/db/knex.js +``` + +## Updating Objection Models + +After schema change, update the corresponding model in `server/models/.js`: +- Add new column to model's `jsonSchema` if validation needed +- Add relation if new FK + +## Safety Rules + +- **Always implement `exports.down`** — enables rollback +- **Never edit a committed migration** — create a new one instead +- **Test rollback** in dev: `migrate:rollback` then `migrate:latest` must both succeed without errors +- **Multi-DB awareness** — migrations run on postgres, mysql, mariadb, mssql, sqlite. Avoid DB-specific SQL. Use Knex schema builder API. + +## Common Mistakes + +| Mistake | Fix | +|---------|-----| +| Missing `exports.down` | Add it — rollback fails silently otherwise | +| Raw SQL with postgres syntax | Use Knex schema API for portability | +| Dropping column without null check | Add `.nullable()` or default first in a prior migration | +| Forgetting to update Objection model | Queries return `undefined` for new column | diff --git a/.claude/skills/wiki-dev-setup/SKILL.md b/.claude/skills/wiki-dev-setup/SKILL.md new file mode 100644 index 00000000..dbb7ab50 --- /dev/null +++ b/.claude/skills/wiki-dev-setup/SKILL.md @@ -0,0 +1,51 @@ +--- +name: wiki-dev-setup +description: Use when setting up local Wiki.js dev environment from scratch — first run, new machine, devcontainer, or after clone +--- + +# Wiki.js Local Dev Setup + +## Steps + +1. **Node version** — use `.nvmrc` (v24.12.0): + ```bash + nvm use + ``` + +2. **Install deps:** + ```bash + yarn install + ``` + `patch-package` runs automatically via `postinstall`. + +3. **Config file** — copy sample, never commit `config.yml`: + ```bash + cp config.sample.yml config.yml + ``` + Edit `config.yml`: set `db.type`, host/port/user/pass, and `port` (default 3000). + +4. **Database** — create the DB manually in postgres/mysql/sqlite first. Wiki.js runs migrations on first start. + +5. **Start dev server:** + ```bash + yarn dev + ``` + Webpack HMR + Node server. Client rebuilds on save. Server requires manual restart on server-side changes. + +6. **First-run setup wizard** — browse to `http://localhost:3000`. Complete setup to create admin account and finish DB migration. + +## Notes + +- `yarn dev` uses `cross-env NODE_OPTIONS=--openssl-legacy-provider` — required for webpack 4 on Node 20+. Do not strip it. +- `yarn watch` builds client only (no server). Use when you want webpack watch without starting the server. +- Devcontainer config at `.devcontainer/devcontainer.json` — use if Docker preferred. +- `save-exact = true` in `.npmrc` — never add `^` to package versions. + +## Common Issues + +| Problem | Fix | +|---------|-----| +| `ERR_OSSL_EVP_UNSUPPORTED` | Missing `NODE_OPTIONS=--openssl-legacy-provider`. Use `yarn dev` not `node dev`. | +| DB connection refused | DB must exist before starting. Wiki.js creates tables, not the DB itself. | +| Blank page after start | Assets not built. Run `yarn build` or use `yarn dev` (includes webpack). | +| patch-package errors | Delete `node_modules`, re-run `yarn install`. | diff --git a/.claude/skills/wiki-graphql-change/SKILL.md b/.claude/skills/wiki-graphql-change/SKILL.md new file mode 100644 index 00000000..75503528 --- /dev/null +++ b/.claude/skills/wiki-graphql-change/SKILL.md @@ -0,0 +1,52 @@ +--- +name: wiki-graphql-change +description: Use when making changes that touch GraphQL schema, resolvers, or client queries together — any cross-layer GraphQL modification +--- + +# GraphQL Cross-Layer Changes + +Wiki.js uses Apollo (server: `apollo-server-express`, client: `apollo-client` 2.x). Changes typically span 3 layers. + +## Layers + +| Layer | Location | What to change | +|-------|----------|----------------| +| Schema (SDL) | `server/graph/schemas/*.graphql` | Type definitions, queries, mutations | +| Resolvers | `server/graph/resolvers/*.js` | Business logic, DB calls via Objection | +| Client queries | `client/graph/*.gql` or inline `gql` tags in `.vue` files | Apollo operations | + +## Workflow + +### 1. Schema first +Edit `.graphql` SDL file. Add field/type/query/mutation. + +### 2. Resolver +Add corresponding resolver in matching `server/graph/resolvers/.js`. Resolvers export object matching schema structure. + +### 3. Client query/mutation +Add or update `.gql` file (or inline `gql` tag). Import via babel `graphql-tag` plugin — no manual parse needed. + +### 4. Apollo cache (if needed) +If mutation changes cached data, update `update` callback in `this.$apollo.mutate(...)` or add `refetchQueries`. Stale cache causes silent UI bugs. + +### 5. Verify +```bash +yarn dev # server logs schema errors on startup +``` +Check browser Apollo devtools for query shape. Run `yarn test` for ESLint pass. + +## Conventions + +- Resolver files mirror schema files 1:1 by domain (e.g. `pages.graphql` ↔ `pages.js`) +- Mutations return typed responses — add `ResponseStatus` fields when following existing pattern +- `graphql-rate-limit-directive` used on some resolvers — add `@rateLimit` if mutation is user-facing +- Subscriptions use `graphql-subscriptions` PubSub — not WebSocket transport directly + +## Common Mistakes + +| Mistake | Fix | +|---------|-----| +| Schema added, resolver missing | Server throws on first call — check resolver export shape | +| Client query shape mismatch | Apollo logs warning; check field names match SDL exactly | +| Cache not updated after mutation | Add `refetchQueries` or manual `cache.writeQuery` | +| Breaking schema change | Existing clients 404 or error — coordinate with any deployed instances | diff --git a/.claude/skills/wiki-new-renderer/SKILL.md b/.claude/skills/wiki-new-renderer/SKILL.md new file mode 100644 index 00000000..fa20f419 --- /dev/null +++ b/.claude/skills/wiki-new-renderer/SKILL.md @@ -0,0 +1,66 @@ +--- +name: wiki-new-renderer +description: Use when adding a new markdown rendering module or custom syntax renderer to this Wiki.js fork +--- + +# Adding a Rendering Module + +Rendering modules live in `server/modules/rendering/`. Each is a directory with a `definition.yml` and an `index.js`. + +## Steps + +### 1. Create module directory +``` +server/modules/rendering// + definition.yml + index.js +``` + +### 2. `definition.yml` — module metadata +Copy from existing module (e.g. `server/modules/rendering/markdown-core/definition.yml`). Key fields: +```yaml +key: your-module-name +title: Your Module Title +description: What it does +author: Your Name +input: markdown # or html +output: html +icon: mdi-language-markdown +enabledDefault: false +props: {} # configurable options; empty if none +``` + +### 3. `index.js` — renderer logic +```js +module.exports = { + async render ({ input }) { + // transform input string, return html string + return transformedHtml + } +} +``` +- `input` is a string (markdown or html depending on `definition.yml`) +- Must return a string +- Async OK — can call external libs + +### 4. Register (auto-discovery) +Wiki.js uses `auto-load` — no manual registration needed. Module loads on server restart. + +### 5. Test +```bash +# Run jest tests for rendering helpers +yarn test +``` +Integration: enable module in Admin → Rendering pipeline and verify output in a wiki page. + +## Custom Couchbase Renderer Pattern + +The topology renderer (`@couchbaselabs/topology-ui`) wraps a fenced code block parser. See `server/modules/rendering/markdown-couchbase-topology/` for the established pattern if adding similar diagram renderers. + +## Common Mistakes + +| Mistake | Fix | +|---------|-----| +| Module not appearing in Admin UI | Check `definition.yml` syntax — YAML parse error silently skips module | +| `input`/`output` mismatch | Pipeline order matters — renderer must receive correct type | +| Mutating `input` string | Return new string, don't modify in place | diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 00000000..514b66e4 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,50 @@ +# CLAUDE.md + +## Project Rules +- This is a fork of Wiki.js (AGPL-3.0) with Couchbase-specific extensions. Keep custom code isolated. +- Node ≥20 required. Pin exact versions — `save-exact = true` in `.npmrc`, no `^` prefixes. +- Use `yarn`, not `npm`. Lock file is `yarn.lock`. +- Never commit `config.yml` (sensitive). Only `config.sample.yml` is tracked. +- `NODE_OPTIONS=--openssl-legacy-provider` required for webpack commands (set via `cross-env` in scripts). + +## Commands +- `yarn install` — install deps (runs `patch-package` postinstall automatically) +- `yarn dev` — start dev server with HMR (webpack dev middleware + Node server on port 3000) +- `yarn build` — production webpack build +- `yarn watch` — webpack watch mode (client only, no server restart) +- `yarn test` — ESLint + pug-lint + Jest (full suite) +- `node server` — start production server (requires built assets + `config.yml`) + +## Workflow +- Client code lives in `client/` (Vue 2 + Vuetify 2 + Apollo). Server in `server/`. +- GraphQL API defined in `server/graph/schemas/` (SDL) and `server/graph/resolvers/`. +- New rendering modules go in `server/modules/rendering/` — see existing modules for pattern. +- New client components go in `client/components/` as `.vue` SFCs. +- After client changes: run `yarn build` or verify via `yarn dev` before marking done. +- Tests in `server/test/` — run `yarn test` before finishing any server-side change. + +## Code Style +- ESLint config: `eslint-config-requarks` + `plugin:vue/strongly-recommended`. No overrides without reason. +- Pug templates: 2-space indent, single-quote attrs, `validateDivTags` enforced (see `pugLintConfig` in `package.json`). +- No TypeScript — plain JS (babel-eslint parser, ES2017+). +- Apollo GraphQL queries defined inline with `graphql-tag` babel plugin (tag: `gql`). + +## Architecture Notes +- Vue 2 + Vuex + Vue Router + Apollo Client (not Vue 3). Do not introduce Vue 3 APIs. +- `@couchbaselabs/topology-ui` is a custom Couchbase package for topology diagram rendering. +- Server uses Objection.js (Knex-based ORM). DB migrations live in `server/db/migrations/`. +- Auth uses Passport.js with many strategies — new auth modules go in `server/modules/authentication/`. +- GraphQL subscriptions via `subscriptions-transport-ws` (not `graphql-ws`). +- Custom markdown renderers registered as modules in `server/modules/rendering/`. + +## Safety / Stop Conditions +- Ask before touching `server/db/migrations/` — migrations are irreversible once run. +- Ask before modifying `server/graph/schemas/` in a breaking way — schema changes affect all clients. +- Do not modify `patches/` files without understanding the patched package's behavior. +- Ask before changing auth or permission middleware (`server/middlewares/`). +- `yarn.lock` changes from `yarn upgrade` need explicit user approval. + +## Context Management +- Keep context lean: read only files relevant to the current feature area. +- Use skills for occasional workflows (PR creation, review, deployment). +- On compact: preserve modified file list, commands run, test output, and any migration state.