From 690e1251df00696d70179a15ed48e9174ed3adde Mon Sep 17 00:00:00 2001 From: "Alina G." Date: Sat, 26 Sep 2026 12:30:37 +1200 Subject: [PATCH] docs: update coding standards Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .github/copilot-instructions.md | 3 +++ .github/instructions/astro.instructions.md | 7 ++++++ .../code-standards.instructions.md | 22 +++++++++++++++++++ .github/instructions/drizzle.instructions.md | 11 ++++++++-- .github/instructions/ui.instructions.md | 2 +- README.md | 4 ++++ eslint.config.js | 14 ++++++++++++ 7 files changed, 60 insertions(+), 3 deletions(-) create mode 100644 .github/instructions/code-standards.instructions.md diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index c1674aa..c4aa7b7 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -35,6 +35,9 @@ This is a crowdfunding platform for games with a developer theme. The applicatio ### Code formatting requirements - Use TypeScript with explicit types for function parameters and return values, especially in the data layer (`db/`, `src/lib/`) +- Follow [`code-standards.instructions.md`](instructions/code-standards.instructions.md) for comment philosophy and TypeScript formatting +- Document every exported function in `db/` and `src/lib/` with TSDoc, including its purpose, parameters, and return value +- Document reusable Astro component `Props` interfaces; see [`astro.instructions.md`](instructions/astro.instructions.md) - Frontend code (TypeScript, Astro) must pass ESLint checks (`npm run lint`) ### Data Layer Patterns (Drizzle + Node SQLite) diff --git a/.github/instructions/astro.instructions.md b/.github/instructions/astro.instructions.md index 43fbda8..3989310 100644 --- a/.github/instructions/astro.instructions.md +++ b/.github/instructions/astro.instructions.md @@ -114,9 +114,16 @@ There is no Svelte/React layer. When a page genuinely needs client behaviour, ad - Run `npx astro sync` to (re)generate route/content types before linting or type-checking - `.astro` files are type-checked by `npm run typecheck:astro` (which runs `astro sync` then `astro check`), on the classic `typescript` package. The pure TypeScript in `db/`, `src/lib/`, and `src/types/` is type-checked separately by `npm run typecheck` (the native TS 7 compiler, `tsgo`), which does **not** process `.astro` files. +### Component Props Documentation + +- Every reusable component must document its `Props` interface with a concise TSDoc comment stating the component's purpose. +- Make each prop's name and type self-explanatory; add a property comment when its meaning, default, or rendering behavior is not clear from the type. +- Keep the documentation accurate when props or component behavior change. + ## Best Practices - Keep data fetching in frontmatter (build time); avoid client-side fetching - Minimize client-side JavaScript — the default is zero JS shipped - Import and use global CSS styles from layouts - Always include a `data-testid` on interactive elements (see `ui.instructions.md`) +- Explain intent and non-obvious decisions in comments; do not restate the code. See [`code-standards.instructions.md`](code-standards.instructions.md). diff --git a/.github/instructions/code-standards.instructions.md b/.github/instructions/code-standards.instructions.md new file mode 100644 index 0000000..19351ed --- /dev/null +++ b/.github/instructions/code-standards.instructions.md @@ -0,0 +1,22 @@ +--- +description: 'Comment philosophy and TypeScript formatting standards' +applyTo: '**/*.{ts,astro,css}' +--- + +# Code Comment and TypeScript Style + +## Comments and documentation + +- Explain **why** code exists or why a non-obvious decision was made; do not narrate mechanics or restate what the code already says. +- Keep comments concise and close to the code they explain. Remove comments that add no context. +- Treat stale comments and documentation as bugs. Update or remove them in the same change as the related code. +- Use TSDoc for exported functions in `db/` and `src/lib/`, following [`drizzle.instructions.md`](drizzle.instructions.md). +- Document reusable Astro component `Props` interfaces so their public API is clear, following [`astro.instructions.md`](astro.instructions.md). + +## TypeScript formatting + +- In application `.ts` files, indent with four spaces; do not use tabs. Playwright specs in `e2e-tests/` and `playwright.config.ts` use two spaces. +- In `.ts` files, use single quotes for strings unless escaping would be required. +- In `.ts` files, end statements with semicolons. +- Keep explicit parameter and return types on functions, especially in `db/` and `src/lib/`. +- ESLint enforces indentation, quote style, and semicolons in `.ts` files. Follow the existing rules rather than adding local formatting exceptions. diff --git a/.github/instructions/drizzle.instructions.md b/.github/instructions/drizzle.instructions.md index 48e19d8..efd14b8 100644 --- a/.github/instructions/drizzle.instructions.md +++ b/.github/instructions/drizzle.instructions.md @@ -45,12 +45,19 @@ import { asc, count, eq } from 'drizzle-orm'; import type { Database } from './db'; import { games } from '../../db/schema'; +/** + * Returns game identifiers ordered by title. + * @param db - Injectable Drizzle database instance. + * @returns Game identifiers in title order. + */ export async function getAllGameIds(db: Database): Promise { - const rows = await db.select({ id: games.id }).from(games).orderBy(asc(games.title)); - return rows.map((r) => r.id); + const rows = await db.select({ id: games.id }).from(games).orderBy(asc(games.title)); + return rows.map((r) => r.id); } ``` +- Every exported function in `db/` and `src/lib/` must have a TSDoc comment describing its purpose, every parameter, and its return value. Use `@param` for each parameter and `@returns` for the result; document the injectable `db` parameter as the database dependency supplied by callers and tests. +- Keep TSDoc focused on contract and intent. Update or remove it when the function's behavior changes; do not duplicate implementation details that are already clear from the code. - Always `order by` a stable column (title) so static builds are deterministic. - Map raw rows to the app-facing `Game`/`Publisher`/`Category` types in one place; don't leak Drizzle row shapes into components. - Keep ordering/lookup logic in `games.ts`, not in pages. diff --git a/.github/instructions/ui.instructions.md b/.github/instructions/ui.instructions.md index 8df7da8..f5a57ee 100644 --- a/.github/instructions/ui.instructions.md +++ b/.github/instructions/ui.instructions.md @@ -49,7 +49,7 @@ Refer to technology-specific instruction files: - Create reusable components for common UI patterns - Keep components focused on a single responsibility - Use props for configuration, not duplication -- Document component APIs with TypeScript types +- Document each reusable Astro component's `Props` interface so its public API is self-explanatory (see [`astro.instructions.md`](astro.instructions.md)) ## Development Workflow diff --git a/README.md b/README.md index 88c7b8b..2d12f33 100644 --- a/README.md +++ b/README.md @@ -74,6 +74,10 @@ npm run lint ESLint is also run automatically in CI on pull requests to `main`. +## Coding standards + +See the [coding standards instructions](.github/instructions/code-standards.instructions.md) for comment and TypeScript formatting conventions, the [data-layer instructions](.github/instructions/drizzle.instructions.md) for exported-function TSDoc requirements, and the [Astro instructions](.github/instructions/astro.instructions.md) for reusable component `Props` documentation. + ## Type checking The project runs on **TypeScript 7** (the native Go compiler, `tsgo`) for type checking, adopted side-by-side via the [`@typescript/native-preview`](https://www.npmjs.com/package/@typescript/native-preview) package. The classic `typescript` package is intentionally kept at v6 so ESLint + `typescript-eslint` and `astro check` keep working unchanged — TypeScript 7's programmatic API isn't ready for those tools yet. diff --git a/eslint.config.js b/eslint.config.js index 51895c0..f953b4c 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -36,8 +36,22 @@ export default [ // TypeScript-specific overrides { files: ["**/*.ts"], + ignores: ["**/*.astro", "**/*.astro/**"], languageOptions: { parser: tseslint.parser, }, + rules: { + indent: ["error", 4, { SwitchCase: 1 }], + quotes: ["error", "single", { avoidEscape: true }], + semi: ["error", "always"], + }, + }, + + // Playwright specs and config use two-space indentation. + { + files: ["e2e-tests/**/*.ts", "playwright.config.ts"], + rules: { + indent: ["error", 2, { SwitchCase: 1 }], + }, }, ];