Initial Commit
This commit is contained in:
463
GENERIC-CLAUDE.md
Normal file
463
GENERIC-CLAUDE.md
Normal file
@@ -0,0 +1,463 @@
|
||||
# Project Engineering Standards (Generic CLAUDE.md)
|
||||
|
||||
A reusable engineering rulebook for AI coding agents and human contributors. Drop into any TypeScript monorepo; replace bracketed `<placeholders>` with project-specific values. Paired with **GENERIC-OPENSPEC-AGENTS.md** for the change-management workflow.
|
||||
|
||||
---
|
||||
|
||||
## 1. Stack baseline (adjust to your project)
|
||||
|
||||
- **Monorepo orchestrator**: Turborepo (or Nx / Lerna / Moon).
|
||||
- **Package manager / runtime**: Bun (or pnpm / npm / yarn).
|
||||
- **Lint / format**: Biome (or ESLint + Prettier).
|
||||
- **Unit tests**: Vitest (or Bun test / Jest).
|
||||
- **E2E**: Playwright.
|
||||
- **Language**: TypeScript, strict.
|
||||
- **Registry**: private (Verdaccio / GitHub Packages) or public npm.
|
||||
|
||||
Pin every tool version in the root manifest; never accept "latest" implicitly.
|
||||
|
||||
---
|
||||
|
||||
## 2. Change workflow
|
||||
|
||||
All non-trivial changes go through the **OpenSpec** process (see `GENERIC-OPENSPEC-AGENTS.md`). Before coding:
|
||||
|
||||
1. Read the project's spec/agents docs.
|
||||
2. Create `openspec/changes/<change-id>/` with `proposal.md`, `tasks.md`, and spec deltas under `specs/<capability>/spec.md` using `## ADDED` / `## MODIFIED` / `## REMOVED Requirements` headings.
|
||||
3. On ship: fold the delta into `openspec/specs/<capability>/spec.md` and move the folder to `openspec/archive/<yyyy-mm-dd>-<change-id>/`.
|
||||
|
||||
---
|
||||
|
||||
## 3. Critical rules (never compromise)
|
||||
|
||||
1. **Never run `tsc` directly.** Use your bundler (Vite/tsup/esbuild) via your task runner. Native TS runtimes (Bun, ts-node) execute `.ts` files without compilation.
|
||||
2. **Never use mocks** for things you can run for real. Prefer real services (testcontainers, in-memory adapters, local servers) over `vi.mock`/`jest.mock`.
|
||||
3. **Pin exact versions** in dependency overrides. No drift.
|
||||
4. **Never re-export external deps** for convenience — consumers import from the upstream source.
|
||||
5. **Never auto-commit/push** without user approval. Never use `--no-verify`.
|
||||
6. **Always use absolute paths** in tool calls.
|
||||
7. **Read files before editing them** — understand context first.
|
||||
8. **Testing-infrastructure packages must not depend on the project's runtime packages.** Only external deps (and a zero-runtime types package, if you have one).
|
||||
9. **Never write static-analysis suppression comments** (`// biome-ignore`, `// eslint-disable*`, `// ts-ignore`, `// ts-expect-error`) in new or migrated code. Stale rule names break the lint gate; comments that no longer apply produce "has no effect" warnings. To exercise a deliberate violation, use a pattern the linter cannot statically reject (see §10b).
|
||||
10. **Never write `export *` in any non-root barrel.** Feature-module barrels MUST use explicit named re-exports. Exempt: generated forwarder files, single-line variant forwarders, and namespace re-exports (`export * as ns from "..."`). Migrate `export *` → named exports inside the same commit, never as a follow-up.
|
||||
11. **Never import test-runner primitives directly from your runner.** If you support both Bun and Vitest (or want to keep the option open), route all test imports through a single neutral wrapper module that re-exports from the active runner via conditional exports. Allowlist only the wrapper packages.
|
||||
|
||||
---
|
||||
|
||||
## 4. Git safety (non-negotiable)
|
||||
|
||||
Before ANY git operation: run `git status` in **every** worktree (`git worktree list`) and confirm each is clean or its state is understood.
|
||||
|
||||
**Never run these without explicit per-use user approval:**
|
||||
|
||||
- `git filter-repo` / `git filter-branch` — rewrites history, destroys staged + working tree.
|
||||
- `git push --force` / `--force-with-lease` — only after the user explicitly says "force push".
|
||||
- `git reset --hard`, `git clean -fd`, `git rebase`, `git stash drop`/`clear`, `git gc`/`prune`, `git checkout -- <file>`.
|
||||
|
||||
**Large-file push errors:** stop. Do NOT rewrite history. Run `git status` / `git stash list` in all worktrees, then ask the user (`.gitignore` + new commit, Git LFS, or manual removal).
|
||||
|
||||
Staged changes are irreplaceable — treat them as more precious than committed history.
|
||||
|
||||
---
|
||||
|
||||
## 5. Workflow rules
|
||||
|
||||
1. **Create a task list for multi-step work** (>3 steps).
|
||||
2. **Complete all implementations.** No stubs, no placeholders, no TODOs, no mocks in production. Missing dep? Add it and wire the real implementation.
|
||||
3. **Build feature-rich, production-grade packages.** Prefer comprehensive over MVP. Every package ships at full functional completeness on first landing — never defer a feature its name reasonably implies to a follow-up proposal.
|
||||
4. **Professional honesty.** No marketing language. No fake metrics.
|
||||
5. **Preserve the full public surface** during rewrites. Trim only when duplicated in-repo or replaceable by an existing in-repo library.
|
||||
|
||||
---
|
||||
|
||||
## 6. Package layout
|
||||
|
||||
### 6.1 Directory structure
|
||||
|
||||
Domain-first organization, with **per-feature folders** containing five co-located files:
|
||||
|
||||
```text
|
||||
src/<category>/
|
||||
<feature>/
|
||||
index.ts # Barrel — explicit named re-exports
|
||||
<feature>.ts # Implementation
|
||||
<feature>.test.ts # Unit tests
|
||||
<feature>.types.ts # Type definitions (optional)
|
||||
<feature>.md # Co-located documentation (mandatory for impl files)
|
||||
```
|
||||
|
||||
Special directories:
|
||||
|
||||
- `types/` — shared types, flat
|
||||
- `utils/` — flat with tests + docs
|
||||
- `constants/index.ts` — simple exports (no tests/docs needed)
|
||||
|
||||
### 6.2 Naming rules
|
||||
|
||||
- **No package-name prefix inside package folders.** Inside `packages/<pkg>/`, child folders/files use the feature name only — never `<pkg>-<feature>`. The package name is already in the path.
|
||||
- **No redundant ancestor names.** A child name must not contain the singular or plural form of any ancestor folder. If parent is `adapters/`, children must not be `memory-adapter/`; use `memory/`. Apply to: `strategies`, `providers`, `builders`, `plugins`, `handlers`, `resolvers`, `factories`, `parsers`, `services`, etc.
|
||||
- **One `README.md` per package root only.** No category-level READMEs inside `src/<category>/`.
|
||||
|
||||
### 6.3 Subpath exports
|
||||
|
||||
Every feature directory must have its own entry in `package.json` `exports` so consumers can tree-shake:
|
||||
|
||||
```json
|
||||
"./retry/retry": {
|
||||
"import": { "types": "./dist/retry/retry.d.ts", "default": "./dist/retry/retry.js" }
|
||||
}
|
||||
```
|
||||
|
||||
A single `"."` barrel is insufficient. The count of subpath exports should match the count of feature modules.
|
||||
|
||||
### 6.4 Barrel rules (explicit named exports only)
|
||||
|
||||
```ts
|
||||
// CORRECT — feature barrel: explicit named exports
|
||||
export {
|
||||
decryptStream,
|
||||
type DecryptStreamOptions,
|
||||
encryptStream,
|
||||
type EncryptStreamOptions,
|
||||
} from "./streaming.js";
|
||||
|
||||
// WRONG — leaks every new export silently
|
||||
export * from "./streaming.js";
|
||||
|
||||
// CORRECT — top-level namespace re-export (recommended for primitives with shared names)
|
||||
export * as ed25519 from "./primitives/ed25519/ed25519.js";
|
||||
```
|
||||
|
||||
Why: the barrel **is** the contract; `export *` makes the contract whatever the source happens to declare today. Tree-shaking is equivalent under `"sideEffects": false`.
|
||||
|
||||
---
|
||||
|
||||
## 7. Dependency conventions
|
||||
|
||||
- **External deps** use catalog refs (or workspace-level pinning) — never bare versions like `"^1.2.3"`.
|
||||
- **Internal deps** use `workspace:^`.
|
||||
- `"sideEffects": false` on all pure library packages.
|
||||
- After changing `overrides`, nuke and reinstall:
|
||||
|
||||
```bash
|
||||
rm -rf node_modules <lockfile> && find . -type d -name "node_modules" -exec rm -rf {} + && <install>
|
||||
```
|
||||
|
||||
- For browser/React packages: verify only one React version exists after install:
|
||||
|
||||
```bash
|
||||
find . -path "*/node_modules/react/package.json" | head -5
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. Banned patterns in `src/`
|
||||
|
||||
Before closing any task, scan for zero matches:
|
||||
|
||||
```bash
|
||||
grep -rn "@deprecated\|TODO\|FIXME\|ts-ignore\|ts-expect-error\|\.skip\|\.only\|\bany\b\|console\.log" \
|
||||
packages/<pkg>/src/ --include="*.ts"
|
||||
```
|
||||
|
||||
- `@deprecated` JSDoc → replace with prose: "Backwards-compatibility alias for X."
|
||||
- `any` → use `unknown` (narrow via `instanceof` / type guards) or a proper generic. Never substitute `object`, `{}`, or a redundant union.
|
||||
- `console.log` → use a real logger (injectable `LoggerLike` interface preferred).
|
||||
|
||||
### 8.1 No stubs, placeholders, or "WIP" code
|
||||
|
||||
Concretely banned in any commit:
|
||||
|
||||
- **Stub functions** — `throw new Error("not implemented")`, identity pass-throughs that pretend to do work, no-op factories.
|
||||
- **Placeholder types** — `type Foo = unknown`, empty `interface Foo {}`, `as never` hiding incomplete data flow.
|
||||
- **TODO / FIXME / XXX comments** in source AND docs.
|
||||
- **Deprecation aliases without a working replacement.**
|
||||
- **"Phase 1 / Phase 2" splits** where Phase 2 is unwritten and Phase 1 ships a function that doesn't do the thing its name claims.
|
||||
- **Marketing language masking incomplete work** ("comprehensive", "fully-featured" applied to code with unimplemented branches).
|
||||
- **Tautological tests** — `it.todo`, `it.skip`, `expect(true).toBe(true)`, `expect(result).toBeDefined()` standing alone, tests that assert against the exact hardcoded value the implementation returns. Every `it(...)` MUST verify a behavior the implementation could plausibly get wrong.
|
||||
- **Stub docs** — `.md` files that say "TODO", empty Features/API sections, or fail word-count gates.
|
||||
- **Empty test files** kept only to keep coverage thresholds passing.
|
||||
- **Silently dropped spec requirements** — see §2c of the OpenSpec doc. If a requirement is in the spec delta, it ships.
|
||||
|
||||
If the work isn't ready: don't merge it. The default branch is the product, not a scratchpad.
|
||||
|
||||
### 8.2 Never delete spec elements to satisfy a gate
|
||||
|
||||
When a gate fails because a registered element (error code, schema field, event topic) is **declared but unused**, the failure is telling you the implementation hasn't caught up to the proposal. **Wire it in**, do NOT delete it. Deletion is the path of least resistance and silently strips features the proposal committed to.
|
||||
|
||||
If the element genuinely crept in by mistake, remove it with a one-line note under `### Deferred` or `### Removed` in `proposal.md` so the deletion is auditable.
|
||||
|
||||
### 8.3 Never delete code that serves a purpose to make tests pass
|
||||
|
||||
When a coverage report flags a function, branch, or guard as uncovered, write a test that exercises real behavior — do NOT delete the code that's hard to reach.
|
||||
|
||||
Concretely banned:
|
||||
|
||||
- Deleting defensive guards because current call sites don't trigger them.
|
||||
- Deleting rollback/cleanup helpers because the synchronous code path can't reach them.
|
||||
- Replacing `instanceof Error ? cause : undefined` with `cause as Error` to "simplify."
|
||||
- Deleting branches inside `try/catch` because the library doesn't currently throw.
|
||||
|
||||
Instead, in priority order:
|
||||
|
||||
1. **Write a test that exercises the path** — inject a controlled failure (custom storage that throws, custom Clock that returns a chosen instant, AbortSignal scheduled via `queueMicrotask`).
|
||||
2. **Restructure to make the path reachable** without changing semantics (e.g. `await Promise.resolve()` between iterations so a caller-side abort can land).
|
||||
3. **If genuinely unreachable**, annotate with `/* c8 ignore next */` and a comment naming the unreachability proof.
|
||||
|
||||
### 8.4 Suppression workaround pattern
|
||||
|
||||
When a deliberate violation is required (e.g. testing a defensive non-Error branch), use a pattern the linter can't statically reject:
|
||||
|
||||
```ts
|
||||
// BANNED — suppression rots when rule renames.
|
||||
// biome-ignore lint/suspicious/noThrowLiterals: ...
|
||||
throw "literal";
|
||||
|
||||
// REQUIRED — linter can't prove the value isn't Error-like.
|
||||
const failure: unknown = "literal";
|
||||
throw failure;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 9. File-size budgets
|
||||
|
||||
- **Source files**: 300 lines hard / 250 soft.
|
||||
- **Test files**: 500 lines max.
|
||||
- **Functions**: 50 lines soft — extract helpers at natural responsibility boundaries.
|
||||
|
||||
```bash
|
||||
find packages/<pkg>/src -name "*.ts" ! -name "*.test.ts" | \
|
||||
xargs awk 'END { if (NR > 300) print FILENAME, NR " lines" }'
|
||||
```
|
||||
|
||||
Split at natural boundaries. Preserve all public exports.
|
||||
|
||||
---
|
||||
|
||||
## 10. Quality gates
|
||||
|
||||
### 10.1 Coverage
|
||||
|
||||
**100 / 100 / 100 / 100** for every package, no exceptions:
|
||||
|
||||
```ts
|
||||
thresholds: { statements: 100, branches: 100, functions: 100, lines: 100 }
|
||||
```
|
||||
|
||||
The pre-publish gate MUST hard-fail below 100%. Mutation / property / fuzz testing layer on top — they do not substitute.
|
||||
|
||||
### 10.2 Tests
|
||||
|
||||
- Use **Arrange-Act-Assert**.
|
||||
- Name tests after the **behavior**, not the implementation:
|
||||
|
||||
```ts
|
||||
// CORRECT
|
||||
it('returns empty array when no results match', ...)
|
||||
it('throws ValidationError when required field is missing', ...)
|
||||
|
||||
// WRONG
|
||||
it('test1', ...)
|
||||
it('works correctly', ...)
|
||||
it('handleSearch', ...)
|
||||
```
|
||||
|
||||
- File suffixes: `.test.ts` for unit, `.spec.ts` for E2E.
|
||||
- Always pass a timeout: `it(name, { timeout: 5000 }, fn)` (30000 for async-heavy).
|
||||
- Root-cause every failure — never `.skip` or `.only` to ship.
|
||||
- Every UI component needs `.stories.tsx` (default + playground + variants).
|
||||
|
||||
### 10.3 Pre-publish gate
|
||||
|
||||
```bash
|
||||
<task-runner> lint typecheck test --filter=<pkg>
|
||||
<task-runner> test:coverage --filter=<pkg>
|
||||
<task-runner> build --filter=<pkg>
|
||||
```
|
||||
|
||||
All must be green. Single-file test runs are not a substitute for the full-package gate.
|
||||
|
||||
---
|
||||
|
||||
## 11. Documentation
|
||||
|
||||
### 11.1 Sibling `.md` per implementation file
|
||||
|
||||
Every `.ts`/`.tsx` MUST have a sibling `.md`. **Exclusions**: `.test.ts`, `.test.tsx`, `.spec.ts`, `.types.ts` (inside a feature dir), `.stories.tsx`, barrel `index.ts`, `constants/index.ts`.
|
||||
|
||||
**Required sections** (≥200 words excl. code):
|
||||
|
||||
1. **Purpose** (≥2 sentences — what and why)
|
||||
2. **Features** (bullet list)
|
||||
3. **Usage: Basic Example**
|
||||
4. **Usage: Advanced Example**
|
||||
5. **API Reference** (every exported symbol — params, return type, throws)
|
||||
6. **Implementation Notes** (design decisions, limits, edge cases)
|
||||
|
||||
Hard constraints: both simple AND advanced examples mandatory; code must compile with real imports; no marketing/placeholder text; update docs when code changes.
|
||||
|
||||
### 11.2 Three-pass writing workflow
|
||||
|
||||
Never one-shot:
|
||||
|
||||
1. **Read** — full `.ts` file; note every exported symbol, param, thrown error.
|
||||
2. **Structure** — Purpose + Features + API Reference first.
|
||||
3. **Examples** — Basic (simplest happy path), then Advanced (real composition / edge case).
|
||||
|
||||
### 11.3 Doc-drift gate
|
||||
|
||||
When you modify any `<feature>.ts`, you MUST update its sibling `<feature>.md` in the same change if the modification affects:
|
||||
|
||||
- public API surface (added/removed/renamed export, changed types, changed throws)
|
||||
- documented behavior (error codes, side effects, semantics)
|
||||
- examples in the `.md` (must still compile)
|
||||
|
||||
Editing `.ts` without touching `.md` is treated as a defect, identical in severity to a failing test.
|
||||
|
||||
```bash
|
||||
# For every changed .ts, confirm the sibling .md is also touched
|
||||
git diff --name-only HEAD | awk '
|
||||
/\.ts$/ && !/\.test\.ts$/ && !/\.spec\.ts$/ && !/\.types\.ts$/ && !/\/index\.ts$/ {
|
||||
md = $0; sub(/\.ts$/, ".md", md)
|
||||
cmd = "git diff --name-only HEAD -- " md
|
||||
cmd | getline touched; close(cmd)
|
||||
if (touched == "") print "DOC DRIFT: " md " not updated alongside " $0
|
||||
}
|
||||
'
|
||||
```
|
||||
|
||||
### 11.4 Root `README.md`
|
||||
|
||||
Every package needs `README.md` at the root with:
|
||||
|
||||
1. Package name (H1)
|
||||
2. One-paragraph description
|
||||
3. Install command
|
||||
4. Quick-start code example
|
||||
5. **Modules** — links to every co-located `.md` in `src/` via relative paths
|
||||
|
||||
---
|
||||
|
||||
## 12. Type design
|
||||
|
||||
### 12.1 No nested object literals in interfaces
|
||||
|
||||
Every nested object shape must be a named `interface` or `type`.
|
||||
|
||||
```ts
|
||||
// WRONG
|
||||
interface CreateUserOptions {
|
||||
profile: { displayName: string; avatarUrl: string }
|
||||
notifications: { email: boolean; push: boolean }
|
||||
}
|
||||
|
||||
// CORRECT
|
||||
interface UserProfile { displayName: string; avatarUrl: string }
|
||||
interface NotificationPreferences { email: boolean; push: boolean }
|
||||
interface CreateUserOptions { profile: UserProfile; notifications: NotificationPreferences }
|
||||
```
|
||||
|
||||
### 12.2 No inline shapes in function signatures
|
||||
|
||||
```ts
|
||||
// WRONG
|
||||
function createSession(user: { id: string }, opts: { ttl: number }): { token: string } { ... }
|
||||
|
||||
// CORRECT
|
||||
function createSession(user: SessionUser, opts: SessionOptions): SessionResult { ... }
|
||||
```
|
||||
|
||||
### 12.3 Shared types belong in a zero-dep types package
|
||||
|
||||
If a type is referenced by ≥2 packages, define it in a shared `types`/`contracts` package with zero runtime code and zero workspace deps. This prevents circular dependencies and makes the public contract single-sourced.
|
||||
|
||||
---
|
||||
|
||||
## 13. Error handling
|
||||
|
||||
Use a centralized error system (`defineCodes("<NAMESPACE>", ["REASON_A", "REASON_B"] as const)` style) rather than hand-written string literals. Rules:
|
||||
|
||||
- **In code**: throw `new XxxError(CODES.REASON, …)` using the exported constant. Never type the raw `"NAMESPACE.REASON"` string by hand.
|
||||
- **In tests**: assert against the constant (`expect(err.code).toBe(CODES.REASON)`), never against a hand-typed literal — those rot silently.
|
||||
- **In specs**: when a spec references a code, use the exact namespaced form. Spec values must match the code-generated value verbatim.
|
||||
- **On mismatch**: fix the spec to match the convention-correct value — do not bend the code's namespace to match a mistaken literal.
|
||||
|
||||
Every registered error code MUST be reachable from a real call site exercised by a test. A registered-but-never-used code is a defect.
|
||||
|
||||
---
|
||||
|
||||
## 14. Web app / page verification
|
||||
|
||||
When generating client-side pages, verification is NOT optional and a 200 response is NOT proof of correctness:
|
||||
|
||||
1. **Staging environment** — mirror production before declaring done (Docker / preview deploy).
|
||||
2. **Full Playwright E2E sweep** — every page, every component, every navigation.
|
||||
3. **Never trust HTTP 200 alone** — verify rendered DOM contains expected content.
|
||||
4. **Inspect browser console** — any unexpected error or warning fails the check.
|
||||
5. **Inspect network activity** — failed requests, missing assets, CORS, mixed content.
|
||||
6. **Zero-defect to live** — fix root cause first.
|
||||
|
||||
---
|
||||
|
||||
## 15. Vitest / WSL2 specifics (optional, if applicable)
|
||||
|
||||
- Use a shared `createTestConfig()` helper. For configs needing aliases/plugins, write standalone with `pool: 'forks'` + a polyfills setup file.
|
||||
- **Never `mergeConfig` with a base config** that may omit polyfills — causes `crypto is not defined` and similar at runtime.
|
||||
- **`vmThreads` and `threads` pools fail in Bun on WSL2** — use default `forks`.
|
||||
- **`fileParallelism: false`** required for browser tests.
|
||||
|
||||
---
|
||||
|
||||
## 16. Code-tier organization
|
||||
|
||||
Encode the runtime tier in `package.json` (`"browser"` field, peer deps, `engines`), not in the folder path.
|
||||
|
||||
- **Universal**: ZERO browser/React/Node-only deps.
|
||||
- **Browser**: React/DOM ok.
|
||||
- **Server**: Node.js ok.
|
||||
|
||||
Co-locate tests with source; sibling `.md` docs per implementation file.
|
||||
|
||||
---
|
||||
|
||||
## 17. Package lifecycle
|
||||
|
||||
- **New packages**: add to manifest, regenerate dep graph index.
|
||||
- **Editing**: every package starts at `0.1.0`; bump only at `1.0.0` graduation.
|
||||
- **Pre-publish gate (non-negotiable)**: lint + typecheck + test + 100% coverage on touched modules + build all green.
|
||||
- **Foundation packages**: when changing a widely-consumed package, run the **dependent sweep** (`<task-runner> test --filter=...<pkg>`) before declaring done. Green local tests do not prove you didn't break consumers.
|
||||
|
||||
---
|
||||
|
||||
## 18. Quick reference commands
|
||||
|
||||
```bash
|
||||
# Test one package
|
||||
<task-runner> test --filter=<pkg>
|
||||
|
||||
# Coverage for one package
|
||||
<task-runner> test:coverage --filter=<pkg>
|
||||
|
||||
# Lint + typecheck + tests
|
||||
<task-runner> lint typecheck test --filter=<pkg>
|
||||
|
||||
# Pre-publish gate
|
||||
<task-runner> lint typecheck test build --filter=<pkg> && <task-runner> test:coverage --filter=<pkg>
|
||||
|
||||
# Dependent sweep (foundation packages)
|
||||
<task-runner> test --filter=...<pkg>
|
||||
|
||||
# Changed since main
|
||||
<task-runner> test --filter=...[main]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 19. Behavior-change propagation
|
||||
|
||||
When a change introduces consumer-visible behavior changes (new error code, renamed metric, method that now throws, default that flipped, return shape change), do all three:
|
||||
|
||||
1. **Self-doc**: update sibling `.md` + `README.md` Features section.
|
||||
2. **Dependent surface scan**: `grep -rln "<old-name>" packages/ | grep -v "/dist/\|/<own-pkg>/"`. Every hit needs updating in the same change set.
|
||||
3. **Migration note**: add `## Migration` to `proposal.md` listing old behavior, new behavior, search command for consumers, recommended replacement.
|
||||
Reference in New Issue
Block a user