Skip to content

Commit 0aa0b39

Browse files
author
aligneddev
committed
updated copilot-instructions
1 parent 61e21b8 commit 0aa0b39

2 files changed

Lines changed: 135 additions & 35 deletions

File tree

Lines changed: 2 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,3 @@
1-
# neCodeBikeTracking Development Guidelines
1+
**This file is superseded by `.github/copilot-instructions.md` in the repository root.**
22

3-
Auto-generated from all feature plans. Last updated: 2026-03-13
4-
5-
## Active Technologies
6-
- TypeScript 5.x (React 19 + Vite); .NET 10 C# / F# backend (unchanged) + `react-router-dom` v7 (new); React 19, Vite, ASP.NET Core Minimal API (existing) (003-user-login)
7-
- `sessionStorage` (client-side auth session only); SQLite via EF Core (existing, unchanged) (003-user-login)
8-
- C# (.NET 10), F# (domain project present), TypeScript (React 19 + Vite) + ASP.NET Core Minimal API, EF Core, React, MSAL auth flow, existing outbox publisher services (004-create-the-record-ride-mvp)
9-
- SQLite local-file profile via EF Core (with existing SQL-compatible patterns) and outbox events table (004-create-the-record-ride-mvp)
10-
11-
- .NET 10 (C#), F# (domain project), TypeScript 5.x (Aurelia 2 frontend) + ASP.NET Core Minimal API, Microsoft Aspire AppHost, Entity Framework Core + SQLite provider, Aurelia 2 + `@aurelia/router`, .NET `System.Security.Cryptography` (PBKDF2), background worker for outbox retry (001-user-signup-pin)
12-
13-
## Project Structure
14-
15-
```text
16-
backend/
17-
frontend/
18-
tests/
19-
```
20-
21-
## Commands
22-
23-
npm test; npm run lint
24-
25-
## Code Style
26-
27-
.NET 10 (C#), F# (domain project), TypeScript 5.x (Aurelia 2 frontend): Follow standard conventions
28-
29-
## Recent Changes
30-
- 004-create-the-record-ride-mvp: Added C# (.NET 10), F# (domain project present), TypeScript (React 19 + Vite) + ASP.NET Core Minimal API, EF Core, React, MSAL auth flow, existing outbox publisher services
31-
- 003-user-login: Added TypeScript 5.x (React 19 + Vite); .NET 10 C# / F# backend (unchanged) + `react-router-dom` v7 (new); React 19, Vite, ASP.NET Core Minimal API (existing)
32-
33-
- 001-user-signup-pin: Added .NET 10 (C#), F# (domain project), TypeScript 5.x (Aurelia 2 frontend) + ASP.NET Core Minimal API, Microsoft Aspire AppHost, Entity Framework Core + SQLite provider, Aurelia 2 + `@aurelia/router`, .NET `System.Security.Cryptography` (PBKDF2), background worker for outbox retry
34-
35-
<!-- MANUAL ADDITIONS START -->
36-
<!-- MANUAL ADDITIONS END -->
3+
See `.github/copilot-instructions.md` for the current Copilot development guide.

.github/copilot-instructions.md

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
# Bike Tracking: Copilot Development Guide
2+
3+
Local-first commute tracking app using .NET Aspire, Minimal API, F# domain, and React 19 frontend. Built for end-user machines (SQLite-based, no cloud infrastructure required).
4+
5+
## Quick Setup
6+
7+
**Mandatory: Use DevContainer** (all tooling pre-configured).
8+
- `Ctrl+Shift+P` → "Dev Containers: Open Folder in Container"
9+
- Once connected, all dependencies ready (.NET 10 SDK, Node 24+, npm, CSharpier)
10+
11+
**Start the app:**
12+
```bash
13+
dotnet run --project src/BikeTracking.AppHost
14+
```
15+
Aspire Dashboard opens at http://localhost:19629 — launch frontend and API from there.
16+
17+
## Commands
18+
19+
### Backend (.NET 10 / C# / F#)
20+
- **Full solution tests:** `dotnet test BikeTracking.slnx`
21+
- **Single test project:** `dotnet test src/BikeTracking.Api.Tests/BikeTracking.Api.Tests.csproj`
22+
- **Restore deps:** `dotnet restore BikeTracking.slnx`
23+
- **Code formatting:** `csharpier format .` (run from repo root; required before commits)
24+
- **Watch mode (API):** `dotnet watch --project src/BikeTracking.Api` (auto-rebuild on changes)
25+
26+
### Frontend (TypeScript / React 19 / Vite)
27+
From `src/BikeTracking.Frontend`:
28+
- **Dev server:** `npm run dev` (HMR on http://localhost:5173)
29+
- **Build:** `npm run build`
30+
- **Lint:** `npm run lint` (ESLint + Stylelint)
31+
- **Unit tests:** `npm run test:unit` (Vitest; use `--ui` flag for interactive mode)
32+
- **E2E tests:** `npm run test:e2e` (Playwright; runs against live API/DB)
33+
- **Watch unit tests:** `npm run test:unit:watch`
34+
35+
### CI Validation
36+
- **Full CI pipeline:** Run locally before pushing: `dotnet test BikeTracking.slnx && cd src/BikeTracking.Frontend && npm run lint && npm run build && npm run test:unit && npm run test:e2e`
37+
- Tests are run in `.github/workflows/ci.yaml` on all PRs and pushes to main
38+
39+
## Architecture
40+
41+
### Projects
42+
- **BikeTracking.AppHost** — .NET Aspire orchestration; starts API, frontend, and dashboard for local dev
43+
- **BikeTracking.Api** — Minimal API (C#); handles routes, EF Core migrations, outbox publishing
44+
- **BikeTracking.Api.Tests** — xUnit backend tests
45+
- **BikeTracking.Domain.FSharp** — Domain logic (F#): discriminated unions for events, pure functions for state transitions, immutable value objects
46+
- **BikeTracking.Frontend** — React 19 + Vite + TypeScript; form-driven UI with react-router-dom v7 for navigation
47+
- **BikeTracking.ServiceDefaults** — Shared Aspire telemetry and OpenTelemetry wiring (all services configured via this)
48+
49+
### Data Model
50+
- **SQLite** (local user-machine deployment; no database service needed)
51+
- EF Core Code-First migrations auto-applied on startup
52+
- **Outbox pattern**: All domain events written to outbox table; background worker retries with progressive delay (up to 30s) until published
53+
- **Event sourcing**: User registration, login, ride records are immutable events; current state derived from event history
54+
55+
### Layering
56+
57+
**F# Domain Layer (BikeTracking.Domain.FSharp):**
58+
- Pure functions: state transitions, calculations
59+
- Discriminated unions: enforce valid event and command structures
60+
- Immutable types: all domain state immutable by default
61+
- No I/O; no dependencies; trivially testable
62+
63+
**C# API Layer (BikeTracking.Api):**
64+
- Receives commands from frontend (JSON), validates with data annotations
65+
- Calls F# domain functions; receives immutable events
66+
- Writes events to SQLite outbox; EF Core persists
67+
- Minimal API endpoints (no controllers)
68+
- Dependency injection wired via Aspire
69+
70+
**Frontend (React/TypeScript):**
71+
- Form-driven signup (name + PIN), login identify screen
72+
- Client-side validation (required fields, format)
73+
- Server-side validation enforced by API (defense-in-depth)
74+
- sessionStorage for auth tokens (not persisted to disk)
75+
76+
## Key Conventions & Patterns
77+
78+
### Test-Driven Development (TDD)
79+
- **Mandatory red-green-refactor cycle**: Write failing tests first, confirm failure with user, implement, validate all green
80+
- Backend tests (xUnit) target pure domain logic (F#) — 85%+ coverage expected
81+
- Frontend tests: unit tests (Vitest) for components; E2E tests (Playwright) for full-stack signup/login flow against live API
82+
- E2E tests use SQLite DB, throw data away after each test (integration-like behavior)
83+
- Always validate test failures before implementation (prove tests are meaningful, not vacuous)
84+
85+
### F# Domain Patterns
86+
- **Railway Oriented Programming (Result<'T>)**: All domain functions return `Result<'T, Error>` for explicit error handling
87+
- **Discriminated unions**: Commands and Events use DUs to enforce valid states (no invalid combinations)
88+
- **Active patterns**: Optional patterns for complex state matching
89+
- **Immutable records**: All domain types immutable; constructors enforce invariants
90+
- Reference F# docs: https://fsharp.org/
91+
92+
### C# API Patterns
93+
- **Data annotations** on request DTOs: [Required], [StringLength], [EmailAddress], etc. (enforced by ASP.NET Core)
94+
- **Minimal API endpoints**: Map HTTP verbs directly; no controller classes
95+
- **Dependency injection**: Services registered in Program.cs; Aspire handles wiring
96+
- **EF Core DbContext**: QueryTimeout for long-running queries; migrations auto-applied on startup
97+
- Reference: https://learn.microsoft.com/aspnet/core/fundamentals/minimal-apis
98+
99+
### React / TypeScript Frontend
100+
- **React 19 patterns**: Hooks (useState, useEffect), functional components only
101+
- **React Router v7**: useNavigate() for programmatic navigation, useParams() for route params
102+
- **Form handling**: Uncontrolled forms (ref-based) or controlled components (useState); validate before submit
103+
- **Client-side validation**: Required fields, format checks; must match server-side rules
104+
- **No inline CSS**: Use .css files with Stylelint + ESLint rules; import in component
105+
- **Component organization**: One component per file; descriptive PascalCase names; co-locate tests with components
106+
- Reference: https://react.dev/
107+
108+
**TypeScript Type Safety (Critical):**
109+
- **NO `any` types allowed** — use explicit types for all variables, parameters, return values
110+
- **Component props**: Define explicit interface (e.g., `interface SignupFormProps { onSuccess: () => void; }`)
111+
- **API contracts**: Define TypeScript types matching backend DTOs (e.g., `interface UserSignupRequest { name: string; pin: string; }`)
112+
- **React hooks**: Type hook parameters and return values (e.g., `const [name, setName] = useState<string>('')`)
113+
- **Form refs**: Type refs explicitly (e.g., `useRef<HTMLInputElement>(null)`)
114+
- **Event handlers**: Type event objects (e.g., `(e: React.FormEvent<HTMLFormElement>) => void`)
115+
- **Route params**: Define param types (e.g., `interface RouteParams { userId: string; }` then `useParams<RouteParams>()`)
116+
- **Service functions**: Return typed Promises (e.g., `async function identifyUser(name: string, pin: string): Promise<User> { ... }`)
117+
- Use `unknown` only when truly dynamic; narrow with type guards
118+
- Use discriminated unions for state variants (e.g., `type PageState = { status: 'loading' } | { status: 'success'; data: User } | { status: 'error'; message: string }`)
119+
- Reference TypeScript handbook: https://www.typescriptlang.org/docs/
120+
121+
### Event Sourcing & Outbox
122+
- **No direct side effects in domain**: Domain functions are pure; I/O happens at API layer
123+
- **Events are immutable**: Once persisted, events never change; corrections via new events
124+
- **Outbox table**: Every API write also writes to outbox; background job publishes with exponential backoff
125+
- **Idempotency**: Handlers must be safe to re-execute (outbox may retry)
126+
127+
## Local Development Deployment
128+
129+
- **Target deployment**: Local user machines (Windows, macOS, Linux)
130+
- **Database**: SQLite file (default: `biketracking.local.db` in app root; move to user-writable app-data folder for packaged installs)
131+
- **Pre-install safety**: Before schema upgrades, users should back up the SQLite file
132+
- **No separate services needed**: No Docker, no separate database server, no cloud provider required
133+
- **Multi-user setup**: For multi-user requirements on a single machine, consider SQL Server LocalDB or SQL Server Express (future phase)

0 commit comments

Comments
 (0)