Skip to content

Commit d573ce6

Browse files
authored
Merge branch 'main' into docs/public-roadmap
2 parents 3cb8fea + bd0613f commit d573ce6

File tree

5 files changed

+86
-76
lines changed

5 files changed

+86
-76
lines changed

.claude/CLAUDE.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# LFX Changelog — Project Rules
2+
3+
## Project Overview
4+
5+
Monorepo: Turborepo + Yarn 4 workspaces. Angular 20 SSR app at `apps/lfx-changelog`, shared package at `packages/shared` (`@lfx-changelog/shared`), MCP server at `packages/mcp-server`. Express 5 backend, PostgreSQL + Prisma ORM, Auth0, OpenSearch, Slack OAuth, GitHub App webhooks, Datadog APM/RUM. See `docs/` for feature-level documentation.
6+
7+
---
8+
9+
## Styling
10+
11+
- **Tailwind CSS v4** — CSS-first config via `@theme` block in `styles.css`, no `tailwind.config.js`
12+
- **`.css` files only** — no SCSS (Tailwind v4 CSS-first approach makes SCSS unnecessary)
13+
- **Semantic color tokens** — use `bg-surface`, `text-text-primary`, `border-border` etc. (defined as CSS custom properties that swap in `.dark {}` block)
14+
- **Light mode default** — dark mode toggled via `.dark` class on `<html>`
15+
- **ALWAYS use Tailwind CSS in HTML first** instead of custom CSS classes
16+
- Only use custom `.css` when absolutely necessary: complex animations (`@keyframes`), pseudo-elements, prose/markdown styling, complex state selectors
17+
18+
---
19+
20+
## Tooling Preferences
21+
22+
- **Prefer `yarn` workspace scripts/binaries over `npx`** when the tool is in the monorepo deps (e.g., `yarn prisma generate` instead of `npx prisma generate`)
23+
- `npx` is allowed for one-off tools not in the workspace or when required by upstream docs/CI (e.g., `npx playwright`, `npx @modelcontextprotocol/inspector`, `npx tsx`)
24+
- **Always use `docker compose`** instead of `docker-compose`
25+
- **Use `yarn lint` to lint** — not `yarn eslint`

CLAUDE.md renamed to .claude/rules/angular.md

Lines changed: 15 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
1-
# LFX Changelog — Project Rules
2-
3-
## Project Overview
4-
5-
Monorepo: Turborepo + Yarn 4 workspaces. Angular 20 SSR app at `apps/lfx-changelog`, shared package at `packages/shared` (`@lfx-changelog/shared`), MCP server at `packages/mcp-server`. Express 5 backend, PostgreSQL + Prisma ORM, Auth0, OpenSearch, Slack OAuth, GitHub App webhooks, Datadog APM/RUM. See `docs/` for feature-level documentation.
6-
1+
---
2+
paths:
3+
- 'apps/lfx-changelog/src/**'
4+
- 'packages/shared/src/**'
75
---
86

9-
## Angular Component Rules
7+
# Angular Component Rules
108

11-
### File Structure
9+
## File Structure
1210

1311
- **NEVER inline templates or CSS** — always use separate `.html` and `.css` files (`templateUrl` / `styleUrl`), never `template:` or `styles:` in the component decorator
1412
- **Components/directives in own subfolder** — e.g. `shared/components/button/button.component.ts`
@@ -17,7 +15,7 @@ Monorepo: Turborepo + Yarn 4 workspaces. Angular 20 SSR app at `apps/lfx-changel
1715
- Prefix: `lfx`
1816
- Use Angular 20 patterns: standalone components, signal-based inputs/outputs (`input()`, `output()`, `model()`), `computed()`, zoneless
1917

20-
### Forms — ALWAYS Use ReactiveFormsModule (CRITICAL)
18+
## Forms — ALWAYS Use ReactiveFormsModule (CRITICAL)
2119

2220
**ALWAYS use ReactiveFormsModule** for any form inputs:
2321

@@ -75,7 +73,7 @@ export class InputComponent implements ControlValueAccessor {
7573
<input (input)="title.set($event.target.value)" />
7674
```
7775

78-
### Template Rules (CRITICAL)
76+
## Template Rules (CRITICAL)
7977

8078
**NEVER use functions in HTML templates** — use signals, computed values, or pipes:
8179

@@ -93,34 +91,17 @@ export class InputComponent implements ControlValueAccessor {
9391
}
9492
```
9593

96-
**ALWAYS use Tailwind CSS in HTML first** instead of custom CSS classes:
97-
98-
```html
99-
<!-- CORRECT - Tailwind classes -->
100-
<div class="border-border bg-surface flex items-center gap-4 rounded-lg border p-4">
101-
<!-- AVOID - custom CSS class -->
102-
<div class="my-custom-card"></div>
103-
</div>
104-
```
105-
106-
Only use custom `.css` when absolutely necessary:
94+
## Signal Patterns
10795

108-
- Complex animations (`@keyframes`)
109-
- Pseudo-element styling that Tailwind can't handle
110-
- Prose/markdown content styling (e.g. `prose-themed` class)
111-
- State-based styling with complex selectors
112-
113-
### Signal Patterns
114-
115-
#### 1. WritableSignals — Initialize directly for simple values
96+
### 1. WritableSignals — Initialize directly for simple values
11697

11798
```typescript
11899
public loading = signal(false);
119100
public count = signal(0);
120101
public items = signal<string[]>([]);
121102
```
122103

123-
#### 2. Model Signals — Use for two-way binding on presentational props
104+
### 2. Model Signals — Use for two-way binding on presentational props
124105

125106
For properties that require two-way binding (e.g., dialog visibility), use `model()`:
126107

@@ -138,7 +119,7 @@ export class DialogComponent {
138119

139120
**Note:** `model()` is for non-form two-way binding (dialogs, tabs, toggles). For form values, always use `FormControl` with `ReactiveFormsModule`.
140121

141-
#### 3. Computed/toSignal — Use private init functions for complex logic
122+
### 3. Computed/toSignal — Use private init functions for complex logic
142123

143124
```typescript
144125
export class MyComponent {
@@ -157,7 +138,7 @@ export class MyComponent {
157138
}
158139
```
159140

160-
#### 4. Avoid effect() — Use toObservable Instead (CRITICAL)
141+
### 4. Avoid effect() — Use toObservable Instead (CRITICAL)
161142

162143
`effect()` triggers whenever ANY signal in the component updates, not just the signals read inside the effect. This causes unintended re-executions.
163144

@@ -196,7 +177,7 @@ public constructor() {
196177
- Syncing to external systems that need ALL changes
197178
- Simple one-liner side effects with no conditions
198179

199-
#### 5. Component structure order
180+
### 5. Component structure order
200181

201182
1. Private injections (with `readonly`)
202183
2. Public fields from inputs/dialog data (with `readonly`)
@@ -208,50 +189,9 @@ public constructor() {
208189
8. Private initializer functions (grouped together)
209190
9. Other private helper methods
210191

211-
#### 6. Interface placement
192+
### 6. Interface placement
212193

213194
- **Shared interfaces** in `packages/shared/src/interfaces/` — exported via `@lfx-changelog/shared`
214195
- **App-specific interfaces** in `apps/lfx-changelog/src/app/shared/interfaces/`
215196
- Group related interfaces in domain-specific files (e.g., `product.interface.ts`, `user.interface.ts`)
216197
- Never define interfaces inside component files — move them to the shared folder
217-
218-
---
219-
220-
## Styling
221-
222-
- **Tailwind CSS v4** — CSS-first config via `@theme` block in `styles.css`, no `tailwind.config.js`
223-
- **`.css` files only** — no SCSS (Tailwind v4 CSS-first approach makes SCSS unnecessary)
224-
- **Semantic color tokens** — use `bg-surface`, `text-text-primary`, `border-border` etc. (defined as CSS custom properties that swap in `.dark {}` block)
225-
- **Light mode default** — dark mode toggled via `.dark` class on `<html>`
226-
227-
---
228-
229-
## Prisma Migrations (CRITICAL)
230-
231-
When creating Prisma migrations, **always use `--create-only` first** to avoid checksum mismatches:
232-
233-
1. `yarn prisma migrate dev --create-only --name <migration_name>` — generates the SQL file without applying
234-
2. Add the license header to the generated `migration.sql` file:
235-
236-
```sql
237-
-- Copyright The Linux Foundation and each contributor to LFX.
238-
-- SPDX-License-Identifier: MIT
239-
```
240-
241-
3. `yarn prisma migrate dev` — applies the migration (checksum now includes the header)
242-
243-
**NEVER** run `yarn prisma migrate dev --name <name>` directly — it generates and applies in one step, meaning the checksum won't include the license header and modifying the file afterward causes integrity errors on production deploys.
244-
245-
**`migration_lock.toml`** is auto-managed by Prisma and overwritten on every migration command. After running any migration, check if its license header was stripped and re-add it if needed:
246-
247-
```toml
248-
# Copyright The Linux Foundation and each contributor to LFX.
249-
# SPDX-License-Identifier: MIT
250-
```
251-
252-
---
253-
254-
## Tooling Preferences
255-
256-
- **Always use `yarn`** instead of `npx` (e.g., `yarn prisma generate`, NOT `npx prisma generate`)
257-
- **Always use `docker compose`** instead of `docker-compose`

.claude/rules/prisma.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
---
2+
paths:
3+
- 'apps/lfx-changelog/prisma/**'
4+
- 'packages/shared/src/schemas/**'
5+
- 'apps/lfx-changelog/src/server/**'
6+
---
7+
8+
# Prisma Migrations (CRITICAL)
9+
10+
When creating Prisma migrations, **always use `--create-only` first** to avoid checksum mismatches:
11+
12+
1. `yarn prisma migrate dev --create-only --name <migration_name>` — generates the SQL file without applying
13+
2. Add the license header to the generated `migration.sql` file:
14+
15+
```sql
16+
-- Copyright The Linux Foundation and each contributor to LFX.
17+
-- SPDX-License-Identifier: MIT
18+
```
19+
20+
3. `yarn prisma migrate dev` — applies the migration (checksum now includes the header)
21+
22+
**NEVER** run `yarn prisma migrate dev --name <name>` directly — it generates and applies in one step, meaning the checksum won't include the license header and modifying the file afterward causes integrity errors on production deploys.
23+
24+
**`migration_lock.toml`** is auto-managed by Prisma and overwritten on every migration command. After running any migration, check if its license header was stripped and re-add it if needed:
25+
26+
```toml
27+
# Copyright The Linux Foundation and each contributor to LFX.
28+
# SPDX-License-Identifier: MIT
29+
```

.claude/rules/testing.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
---
2+
paths:
3+
- 'apps/lfx-changelog/e2e/**'
4+
- 'apps/lfx-changelog/playwright.config.ts'
5+
---
6+
7+
# E2E Testing (Playwright)
8+
9+
- Config at `apps/lfx-changelog/playwright.config.ts`, uses `.env.e2e` and `http://localhost:4204`
10+
- Run with `yarn test` from `apps/lfx-changelog`
11+
- **Page Object pattern:** one `*.page.ts` per page in `e2e/pages/`, specs import page objects
12+
- **Test structure:** `e2e/specs/admin/` (authenticated), `e2e/specs/public/` (unauthenticated), `e2e/specs/api/` (API tests)
13+
- **Helpers:** `e2e/helpers/` for auth, API, toast, DB, Docker, and test data utilities
14+
- **Setup projects** handle Docker, migrations, and seeding automatically
15+
- Workers: 1 (sequential) — `fullyParallel: false`
16+
- Traces on first retry, screenshots on failure, video retained on failure

docs/database-migrations.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ yarn prisma migrate dev
9292
yarn prisma migrate status
9393
```
9494

95-
> **Important:** Always use `--create-only` first to avoid checksum mismatches. See the `CLAUDE.md` section on Prisma migrations for the full workflow.
95+
> **Important:** Always use `--create-only` first to avoid checksum mismatches. See `.claude/rules/prisma.md` for the full workflow.
9696
9797
## Manual Migrations (Remote Database)
9898

0 commit comments

Comments
 (0)