DimitriGilbert / DimitriGilbert/dbuild

Test & quality alignment plan

Aperta
#1 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub
Lingua principale
TypeScript
Stelle
0
Fork
0
Metriche di merge delle PR
Nessuna PR unita negli ultimi 30g

Descrizione

# Test & Quality Alignment Plan — dbuild

- **Project**: `Dbuild.dev` (`/home/didi/workspace/dbuild`, origin `DimitriGilbert/dbuild`)
- **Date**: 2026-09-05
- **Generated by the fleet test-and-quality alignment initiative** (28-repo audit + synthesis)
- **Audit report**: [`../.test-alignment-audit/reports/dbuild.md`](../.test-alignment-audit/reports/dbuild.md)
- **Fleet synthesis / decisions**: [`../.test-alignment-audit/synthesis-decisions.md`](../.test-alignment-audit/synthesis-decisions.md)
- **Stack reality**: BTS v2.22.10 `next-only` monorepo — Next.js 15.1.3 / React 19 / Tailwind v4 / Turborepo, **Bun-managed** (`packageManager: bun@1.3.6`, `bun.lock`), statically exported to GitHub Pages (`dbuild.dev`). One app (`apps/web`), empty `packages/`. ~9k LOC, 0 test files, no hooks, dead `lint` script (no CI — by owner design, D5; the gate is local commands).

_Revised 2026-09-05: CI removed by owner decision — quality gates are local commands run by the owner/agents; no GitHub Actions._

---

## 1. Adopted decisions (synthesis D1–D7, adapted to a Bun-managed Next.js static site)

| Decision | Adoption for dbuild |
|---|---|
| **D1 — Runner & layout** | **`bun:test` (Bun's built-in runner), NOT vitest.** D1 explicitly rules: "Bun repos: `bun:test` stays … do not introduce vitest" (precedent: email-sdk + FeedElity, 806 cases combined). Adding vitest would bolt a Vite toolchain onto a repo with zero test infra for no benefit. Tests colocated as `*.test.ts(x)` next to source. Root one-command entry `bun run test` via turbo. **Environment: node-only — no jsdom, no RTL.** This is the explicit pick synthesis §5 demands from Next-variant repos: v1 has zero component tests (static site; the value is pure logic), so the DOM stack would be dead weight. |
| **D2 — Coverage** | **Report-only.** Bun's coverage reporter is explicitly not threshold-grade (synthesis §5). Run `bun test --coverage`, record the measured baseline in AGENTS.md, never gate on it. Revisit thresholds when Bun coverage matures. |
| **D3 — Lint** | **ESLint 9 flat config + typescript-eslint ^8 + eslint-plugin-react-hooks** (fleet standard). This retires the dead `lint: "next lint"` script (no ESLint dep or config exists — audit P1) and un-dangles the `lint` task in `turbo.json`. Prettier **deferred** in v1 per D3's allowance — stated in AGENTS.md rather than pretended. |
| **D4 — Quality metrics** | **knip + jscpd, report-only**, local report scripts run on demand by the owner/agents (writing a git-ignored local report). No CRAP (requires threshold-grade coverage Bun can't give), no mutation testing (dbuild is not one of the five nominated cores), no circular-dep tooling in v1. jscpd uses the launch-mommy canonical config (`minLines: 8, minTokens: 80`, `exitCode: 0`). |
| **D5 — no CI by design (owner decision 2026-09-05)** | GitHub Actions rejected fleet-wide: no `.github/workflows`, no reusable-workflow convergence target, no scheduled jobs. Enforcement = the root-level headless verification entrypoint (`bun run verify`: lint → check-types → test → build, composed in Phase 4) run by the owner and by agents; the plan's phase validation gates are run by implementer/validator agents before any phase is declared done. GH Pages deploys stay manual, guarded by a green `bun run verify`. |
| **D6 — Shared config** | Adopt `@dg/config` presets opportunistically (D6: "when it touches lint/tsconfig/vitest anyway") — Phase 1 touches lint, so if `@dg/config` is published at execution time, the ESLint config extends it; otherwise write the local flat config and note it for later convergence. Non-blocking either way. |
| **D7 — Hooks** | **No git hooks.** Local gates run by the owner/agents are the only authoritative gate. AGENTS.md states it explicitly: "the headless local verification command (`bun run verify`) is the quality gate; hooks are local convenience." A repo with no hooks and a green local run is compliant. |

### Deviations from the synthesis (declared, not silent)

1. **Runner**: the dbuild delta block (§4) says "Seed vitest (Bun-compatible)"; the core D1 decision and §5 non-goals say Bun repos keep `bun:test` and must not introduce vitest. **Follow D1: `bun:test`.** Rationale above; zero install, native TS + `tsconfig` `paths` support, fleet precedent.
2. ~~CI workflow~~ **Removed by the 2026-09-05 revision**: no workflow is created (D5); the Bun-vs-pnpm reusable-workflow mismatch that motivated this deviation is moot — the gate is the local `bun run verify` entrypoint.
3. **Package manager**: **Bun stays.** Switching to the pnpm fleet default would mean regenerating the lockfile, re-verifying the GH Pages build chain, and retraining habits for zero test-quality gain — synthesis §5 explicitly lists dbuild among "stay Bun". Kept.
4. **No `packages/config`**: dbuild has no shared-config package (empty `packages/`) — the fleet cross-constant doesn't apply; `apps/web/tsconfig.json` stays hand-maintained. Optional tightening (`noUncheckedIndexedAccess`) is deliberately **not** in scope: it would churn 9k LOC with no test payoff in v1.
5. **Renovate**: the `local>DimitriGilbert` preset reference requires the org preset to exist first (fleet-level task). If it doesn't at execution time, land the one-liner anyway and expect a Renovate warning until the preset lands — or temporarily extend `config:recommended` and switch in a follow-up.

---

## 2. Test-runner decision in one line

**`bun test` over `src/lib/*` pure logic in node env; no jsdom/RTL; coverage report-only.** The testable core (grounded in the audit + read of the code):

- `apps/web/src/lib/seo.ts` (375 LOC) — fully pure: `formatCanonicalUrl`, `formatTitle`, `formatAbsoluteImageUrl`, `formatOpenGraphLocale`, `serializeJsonLd`, `parseTaxonomySlug`/`formatTaxonomySlug`, `create*JsonLd`, `createStaticPageMetadata`, `createNotFoundMetadata`. Highest-value, zero-mock target.
- `apps/web/src/lib/xml-sitemap.ts` (58 LOC) — pure string builders (`createUrlSet`, `createSitemapIndex`); `createXmlResponse` uses the global `Response`, which Bun provides.
- `apps/web/src/lib/blog.ts` (598 LOC) — exported `slugify`; **module-private pure helpers that must be exported (behavior-preserving, mechanical)**: `readString`, `readDateString`, `readStringArray`, `readFrontmatter`, `calculateReadTime`, `generateTOC`, `chooseCanonicalTagName`. fs-backed getters (`getAllPosts` etc.) get one deterministic integration test over the in-repo `content/blog` corpus (55 files, static data — hermetic enough; assert structure, not exact counts).
- `apps/web/src/lib/projects.ts` (62 LOC) — reads in-repo `data/projects.json`: cheap deterministic tests.
- `apps/web/src/lib/mindmap.ts` (440 LOC) — fs + dagre heavy, single re-export surface: **deferred** to a later ratchet; not worth a refactor in v1.
- `apps/web/scripts/validate-content.js` — the de-facto content suite (audit: "a genuine validation program"); predicates are pure but the script exports nothing and self-invokes. Phase 3 splits it so it becomes testable **and** build-gated.

---

## 3. Phased plan

Orchestration model per the `subagent-orchestration` skill: every phase = **1 implementer dispatch → implementer runs gatekeeping commands → 1 validator dispatch (different agent; must read the code, not just run commands) → fix loop (fixer repairs ALL validator findings at once; re-validate; max 3 attempts) → phase done**. All phases are sequential (each builds on the previous gate). Every implementer/fixer dispatch carries the NO-SLOP policy verbatim (no `any`/`as any`, no TODO/FIXME, no unused imports, `import type` for type-only imports, no dev servers — all of which AGENTS.md also mandates). No commits/pushes unless the owner asks; the fleet initiative's rule against destroying uncommitted work applies (the tree currently has uncommitted content/source edits — phases must build around them, never reset them).

### Phase 0 — Resolve the Next.js two-major drift + workspace hygiene

**Goal**: one Next major in the lockfile; root stops shadowing the app's dependency versions; no `npm` in a Bun repo.

**Tasks**
1. `package.json` (root): **delete the `dependencies` block entirely** — it hoists `next ^16.1.3`, `react ^19.2.3`, `react-dom ^19.2.3`, `@types/node ^25.0.9` while `apps/web` pins `next 15.1.3` / `react ^19.0.3` / `@types/node ^22.19.7` (two Next majors and two `@types/node` majors confirmed in `bun.lock`). Nothing at root imports them (root has no source; only `turbo` devDep + `scripts/optimize-image.sh`). Keep the `resolutions` block (correct place for Bun overrides). Optionally rename root package from `Dbuild.dev` to `dbuild` to kill the root/app name collision (nothing references the root name).
2. `apps/web/package.json`: fix the `setup` script — `"setup": "bun run init && bun run setup-content && bun run validate-content"` (currently `npm run …` in a Bun repo; audit P3).
3. From repo root: `bun install` to regenerate `bun.lock`; verify exactly one `next` version (15.1.3) and one `@types/node` version remain.
4. Do NOT touch AGENTS.md/CLAUDE.md here — the docs sweep is Phase 5 (one coherent edit instead of churn).

**Orchestration**: implementer → validator. Validator must read both `package.json` files, diff-check no other script referenced the removed root deps, and confirm lockfile state.

**Validation gate** (from repo root): `bun install --frozen-lockfile` → `bun run check-types` → `bun run build`; plus `grep -o '"next@[0-9.]*"' bun.lock | sort -u` yields exactly `next@15.1.3`.

**Effort**: **S** (small, but it unblocks everything else — the lockfile must be sane before any gated run from a clean checkout with `--frozen-lockfile`).

### Phase 1 — Implement ESLint 9 flat config; retire the dead `next lint`

**Goal**: `lint` runs, lints, and passes; the turbo `lint` task stops being dangling; the "no linting" claim in AGENTS.md becomes false in the good direction.

**Tasks**
1. Install (repo root, Bun workspace): `bun add -d -w eslint@^9 @eslint/js@^9 typescript-eslint@^8 eslint-plugin-react-hooks@^5 globals`
2. Create `apps/web/eslint.config.mjs` (flat config): `@eslint/js` recommended + `typescript-eslint` **type-checked** (`recommendedTypeChecked` with `projectService: true` — feasible: single tsconfig at `apps/web/tsconfig.json`) + `eslint-plugin-react-hooks` recommended (it's a React repo). Ignores: `node_modules/`, `.next/`, `out/`, `next-env.d.ts`, `content/`. Plain-JS `scripts/*.js` get `js.configs.recommended` if type-checked parsing of JS proves noisy — implementer's call, requirement is **zero errors, zero rule disables without cause**.
3. `apps/web/package.json`: replace `"lint": "next lint"` with `"lint": "eslint ."`.
4. `package.json` (root): add `"lint": "turbo lint"` (the turbo `lint` task already exists — it becomes real).
5. `apps/web/next.config.mjs`: **keep** `eslint.ignoreDuringBuilds: true` deliberately — lint is a standalone gate step (in `bun run verify`), not a build-time side effect; add nothing.
6. If `@dg/config` (D6) is published by execution time, extend its ESLint preset instead of hand-rolling; note the choice in the config header comment (comment rule: AGENTS.md bans comments in production code — a one-line provenance note in config files is acceptable, or omit).
7. AGENTS.md: replace the "No Linting/Formatting Config" section with the reality (ESLint 9 flat, `bun run lint`, Prettier deliberately deferred in v1 — D3's "say so rather than pretend").

**Orchestration**: implementer → validator. Validator must read the config and spot-check that the rules actually fire (e.g. introduce nothing; verify ignores don't swallow `src/`), and enforce NO-SLOP.

**Validation gate**: `bun run lint` (root, via turbo) exits 0 with zero errors → `bun run check-types` → `bun run build`. Any pre-existing lint errors are **fixed, not suppressed** (AGENTS.md: never silence; fix the cause — same doctrine as the fleet).

**Effort**: **M** (type-checked lint over 9k LOC can surface a tail of real findings to fix).

### Phase 2 — Seed `bun:test` over `src/lib` pure logic

**Goal**: the repo's first real test suite; headless one-command entry from root.

**Tasks**
1. `apps/web/package.json`: add `"test": "bun test"` and `"test:coverage": "bun test --coverage"`. Root `package.json`: add `"test": "turbo test"`. `turbo.json`: add a `"test"` task (no `dependsOn` build; cacheable).
2. `apps/web/bunfig.toml`: coverage **report-only** config (`[test]` coverage settings; reporters text; no thresholds — D2 Bun exception).
3. Create colocated suites (bun:test, node env, static imports only — AGENTS.md forbids `await import`/`require`):
- `src/lib/seo.test.ts` — canonical URL formatting, title suffixing, OG locale mapping, taxonomy slug parse/format roundtrip, `serializeJsonLd` output, each `create*JsonLd`/`create*Metadata` factory's required fields (~25–35 cases).
- `src/lib/xml-sitemap.test.ts` — URL-set rendering, sitemap index, `createXmlResponse` (Bun's global `Response`).
- `src/lib/blog.test.ts` — `slugify` (assert **current** behavior, e.g. non-ASCII stripping, as regression pins); newly exported `generateTOC`, `calculateReadTime`, `readFrontmatter`, `chooseCanonicalTagName` (make them named exports — behavior-preserving, mechanical diff in `src/lib/blog.ts`); one integration test over the real `content/blog` corpus via `getAllPosts()`: every non-draft post has title/date/tags/summary — assert structure, never exact counts (content churns weekly).
- `src/lib/projects.test.ts` — `getAllProjects` non-empty, `getProjectById` hit/miss→null, tag filter, unique tag list.
4. Explicitly **no jsdom / no `@testing-library/*` / no component tests** in v1 (the pick synthesis §5 requires; static site, zero DOM logic under test).
5. NO-SLOP applies doubly: AGENTS.md itself bans `any`/`as any` — tests use real types from the source modules.

**Orchestration**: this is the one phase worth **two sub-phases**, each with its own validator, plus a mandatory phase-wide validator reading both together (skill Rule 3): (a) infra (scripts, bunfig, turbo) + `seo` + `xml-sitemap`; (b) `blog` (incl. the export refactor) + `projects` + corpus integration. Phase-wide validator checks: import coherence, no duplicated fixtures, coverage config sane.

**Validation gate**: `bun run test` (root) green; `bun run test:coverage` produces a report (record the numbers, gate nothing); `bun run check-types` → `bun run lint` → `bun run build`.

**Effort**: **M**.

### Phase 3 — Gate `validate-content` into the build; make it testable

**Goal**: invalid frontmatter can no longer ship (audit P2: validator is manual-only today, wired only into `setup`).

**Tasks**
1. Split `apps/web/scripts/validate-content.js` (behavior-preserving): extract the pure predicates/collectors — `hasValue`, `readString`, `isDraft`, `isValidDate`, `isStringArray`, `isCategoryIndex`, `normalizeTranslationCandidate`, `hasFrenchSignals`, `likelyTranslatedContent`, `getTranslationCandidate`, `buildTranslationCandidateCounts`, `validatePost` — into `apps/web/scripts/lib/content-rules.js` (ESM **static** exports; no `require`, no `await import`). `validate-content.js` keeps the fs walk, console output, and `process.exitCode` semantics **byte-identical** (the build gate depends on the exit code).
2. Wire the build: `apps/web/package.json` `"build": "node scripts/validate-content.js && node scripts/generate-rss.js && next build"` — validate **first**, so bad frontmatter fails before RSS is generated from it.
3. Create `apps/web/scripts/lib/content-rules.test.js` (bun:test, plain JS): draft skip, category `_index` warnings-vs-errors, invalid date, tags array rule, empty body, French-heuristic detection, duplicate-translation-candidate ⇒ `translationKey` warning, `ogImageAlt` warning — table-driven against synthetic frontmatter objects (no fs).
4. **Contingency**: the live corpus has uncommitted edits; if `validate-content` fails on it during implementation, the implementer must **stop and report** — never weaken the validator or "fix" content silently. That's a real finding for the owner.
5. Add `bun run validate-content` to the AGENTS.md web-commands list (Phase 5 reconciles fully).

**Orchestration**: implementer → validator. Validator diffs old vs new script output on the real corpus (must be identical) and reads the new tests for tautologies (DoD item 9).

**Validation gate**: `bun run validate-content` exits 0 on the current corpus → `bun test` green → `bun run build` (now content-gated) → `bun run check-types`.

**Effort**: **S**.

### Phase 4 — Local gate composition: `bun run verify`

**Goal**: DoD 2 under D5 (no CI by design): typecheck + lint + test + build become one headless root command the owner and agents run before any phase is declared done.

**Tasks**
1. Root `package.json`: add `"verify": "bun run lint && bun run check-types && bun run test && bun run build"` — the headless verification entrypoint (D5). Phases 0–3 already landed each ingredient; this composes them.
2. AGENTS.md: document `bun run verify` as the pre-deploy and pre-phase-done gate.
3. No `.github/` directory is created and no workflow file is written anywhere (D5 — owner decision 2026-09-05).

**Orchestration**: implementer → validator. Validator reads the root `package.json`, confirms the chain is exactly lint → check-types → test → build, then runs `bun run verify` from a clean-install state; fail-fast proven once (deliberate failing test in a scratch copy → non-zero exit at the test step).

**Validation gate**: `bun run verify` exits 0 from repo root; every command in the chain exists in `package.json` files.

**Effort**: **S**.

### Phase 5 — Dependency hygiene, quality report, docs truth

**Goal**: DoD items 5, 7, 8 closed; documentation stops contradicting reality.

**Tasks**
1. `renovate.json` (repo root): `{"$schema": "https://docs.renovatebot.com/renovate-schema.json", "extends": ["local>DimitriGilbert"]}` (deviation D5-5 ordering note applies). dbuild has no `"latest"` pins today — Renovate keeps it that way and watches the `next` 15→16 upgrade path deliberately instead of by lockfile accident.
2. Quality report (report-only, on demand — D4): `bun add -d -w knip jscpd`; add `.jscpd.json` with the launch-mommy canonical config (`minLines: 8`, `minTokens: 80`, `exitCode: 0`, exclude tests/generated — here: `.next`, `out`, `content`); minimal `knip.json` for the Next app. Root scripts `"quality:knip"` / `"quality:jscpd"` write reports to a git-ignored local directory; run on demand by the owner or during a periodic agent pass — no workflow, no schedule, no artifacts (D5).
3. Coverage baseline: run `bun run test:coverage`, record measured lines/branches in AGENTS.md's Testing section as the ratchet baseline (ratchet +5 whenever Bun's tooling becomes threshold-grade; never lower).
4. Docs reconciliation (audit P3, DoD item 5):
- `AGENTS.md`: `bun@1.3.6` (says 1.2.15); Testing section = runner (`bun test`), locations (`src/lib/*.test.ts`, `scripts/lib/*.test.js`), commands (incl. `bun run verify`), coverage baseline + report-only status, the D7 sentence ("the headless local verification command (`bun run verify`) is the quality gate, run by the owner/agents; hooks are local convenience"); Package Management section consistent with the new scripts.
- `CLAUDE.md`: fix "No linting or type checking commands defined at root level" (false — root `check-types`/`lint` exist via turbo), drop the stale `bun run lint` implication, or better: reduce CLAUDE.md to a pointer at AGENTS.md to end the two-file drift permanently (owner's preference wins if they want both files).
5. Optional (only if frictionless): adopt `@dg/config` tsconfig/vitest presets per D6 — explicitly skippable; never a churn PR for its own sake.

**Orchestration**: implementer → validator. Validator greps both docs for every claim and verifies each against the repo (the exact failure mode this phase exists to kill: phantom docs).

**Validation gate**: full chain from root — `bun install --frozen-lockfile && bun run verify && bun run validate-content`; `knip` and `jscpd` run exit 0 (report-only) and produce their local reports.

**Effort**: **M**.

---

## 4. Alignment Definition of Done — per-item status for dbuild

| # | DoD item (synthesis §3) | Current status | Closed by |
|---|---|---|---|
| 1 | Root-level headless test command, documented in AGENTS.md | **Missing** — no `test` script anywhere | Phase 2 + 5 |
| 2 | Headless verification entrypoint runs typecheck + test + lint in one command; agent records green before a phase is done | **Missing** — no root aggregate command | Phase 4 (`bun run verify`) |
| 3 | Coverage measured & reported; baseline recorded; no threshold ever lowered | **Missing** — no runner (Bun exception: report-only, no thresholds) | Phase 2 + 5 |
| 4 | Lint installed, zero errors, wired into the headless entrypoint; dead turbo `lint` task implemented or deleted | **Dead** — `next lint` with no ESLint dep/config; turbo `lint` dangling; `ignoreDuringBuilds: true` | Phase 1 + 4 |
| 5 | AGENTS.md "Testing" section matches reality; no phantom docs | **Partial** — honest about absence, but stale (bun@1.2.15, `npm run` in setup, CLAUDE.md false claims) | Phase 5 |
| 6 | Dead scaffold test deps removed or used | **Met (vacuously)** — no RTL/jsdom scaffold deps present; nothing to remove | n/a (Phase 2 keeps it true: no DOM deps added) |
| 7 | Renovate one-liner; no `"latest"` deps | **Half** — no `"latest"` pins exist; no Renovate config | Phase 5 |
| 8 | Quality-report script (knip + jscpd) runnable locally, report-only | **Missing** | Phase 5 |
| 9 | Nothing satisfied by a fake pass (no `passWithNoTests`, no echo-tests, no tautologies) | **Met today** (nothing exists to fake); enforced going forward by validators reading every test | All phases |

## 5. Risks & repo-specific notes

- **Static-site scope discipline.** No e2e, no component tests, no jsdom/RTL in v1 — value is pure-logic tests + content gating + the local build gate. Resist scope creep toward Playwright; the site has no backend to integration-test.
- **GH Pages deploy coupling.** Deploys are manual `gh-pages` pushes from the owner's machine — that does not change under D5. The contract becomes: a green `bun run verify` immediately before deploy ⇒ the deploy is safe. Risk: the deployed site drifts from `main` if deploys lag — acceptable for a personal site; keep the pre-deploy verify habit documented in AGENTS.md.
- **Content corpus is live data.** 55 markdown files, edited constantly (uncommitted edits in the tree right now). Corpus-integration tests assert structure, never counts; the Phase 3 build gate makes the validator an owner-facing contract — if it fails on real content, that's reported, not papered over.
- **Bun coverage is experimental** — report-only forever until Bun's reporter is threshold-grade (synthesis §5); do not let a later PR add thresholds on top of misreportable numbers.
- **Export-refactor risk (blog.ts, Phase 2)** is mechanical but touches a 598-line file with uncommitted edits — implementer must make the minimal diff (add `export` to existing pure functions, change nothing else) and the validator must diff behavior.
- **`validate-content.js` exit-code semantics are load-bearing** once Phase 3 wires it into `build` — the refactor must not change output format or exit codes.
- **AGENTS.md hard bans** (`await import`, `require`, `any`) bind all test code too; bun:test + static imports comply naturally.
- **Uncommitted work in the tree**: all phases proceed on top of it; no stashing/resetting (fleet rule). Suggest the owner land or set aside current edits before Phase 0 touches the lockfile — `bun install` will rewrite `bun.lock`, which already has uncommitted modifications.

## 6. Effort summary

| Phase | Goal | Effort |
|---|---|---|
| 0 | Next-drift resolution + workspace hygiene | S |
| 1 | ESLint 9 flat config; kill dead `next lint` | M |
| 2 | Seed `bun:test` over `src/lib` (2 sub-phases + phase-wide validation) | M |
| 3 | `validate-content` build-gated + unit-tested | S |
| 4 | Local gate composition (`bun run verify`) | S |
| 5 | Renovate + quality report + docs truth | M |

Total: ~2 focused days of implementer/validator cycles. Sequencing rule: **no phase starts before the previous gate is green**; every gate is runnable from the repo root with the commands listed above.

Guida per i contributori

Nessuna guida per i contributori indicizzata per questo repository

Direzione di ricerca

Inizia con i file root package.json, apps/web/package.json e bun.lock indicati, quindi esamina i gate per fasi e i file esistenti in apps/web/src/lib. Esegui prima i controlli di Phase 0, seguiti dai comandi di verifica locale descritti nel piano; il lavoro è completato quando i gate pianificati di test, lint, type-check, build e report-only quality superano i controlli senza introdurre CI.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
bun, eslint, nextjs, react, tailwindcss, typescript
Ambito
build-system, developer-experience, documentation, testing-qa, tooling
Tipo di issue
Refactoring
Difficoltà
5/5
Tempo stimato
Più di una settimana
Stato di attività
Attiva
Chiarezza
Specificata chiaramente
Idoneità per principianti
35/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.