Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
7 changes: 7 additions & 0 deletions .github/instructions/astro.instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -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).
22 changes: 22 additions & 0 deletions .github/instructions/code-standards.instructions.md
Original file line number Diff line number Diff line change
@@ -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.
11 changes: 9 additions & 2 deletions .github/instructions/drizzle.instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -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<number[]> {
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.
Expand Down
2 changes: 1 addition & 1 deletion .github/instructions/ui.instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
14 changes: 14 additions & 0 deletions eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 }],
},
},
];
Loading