Skip to content
Merged

Dev #19

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
8 changes: 8 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.git
**/node_modules
**/dist
.env
.env.*
coverage
playwright-report
test-results
7 changes: 7 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Used only by the optional Project 2 API and database commands.
# Create this dedicated native PostgreSQL database and role using README.md.
DATABASE_URL=postgresql://t31_dev:change-me@127.0.0.1:5432/t31_project2_dev
API_HOST=127.0.0.1
API_PORT=3001
CORS_ORIGINS=http://localhost:5173,http://127.0.0.1:5173
NODE_ENV=development
2 changes: 2 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# DOM snapshots intentionally preserve rendered text-node spaces.
*.snap whitespace=-blank-at-eol
21 changes: 21 additions & 0 deletions .github/ISSUE_TEMPLATE/task.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
name: Development task
about: Plan a small, reviewable course task
title: ''
labels: ''
assignees: ''
---

## Outcome

What should the user be able to do?

## Course requirement

Link the requirement and explain the chosen approach.

## Acceptance checks

- [ ] Functionality and error states verified
- [ ] Relevant tests and documentation updated
- [ ] Teammate review completed
15 changes: 15 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
## Change

Explain the user-visible problem and resulting behavior. Link the issue: Closes #...

## Verification

List commands actually run and relevant manual/browser checks.

## Course requirements and AI use

Describe affected requirements, architectural decisions, AI assistance, and how the team verified it.

## Review

Request a teammate review. Record follow-up work; do not self-approve.
13 changes: 13 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
node_modules/
dist/
coverage/
playwright-report/
test-results/
.env
.env.*
!.env.example
*.local
*.tsbuildinfo
bun.lock
bun.lockb
.DS_Store
1 change: 1 addition & 0 deletions .node-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
24.21.0
2 changes: 2 additions & 0 deletions .npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
engine-strict=true
save-exact=true
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
24.21.0
7 changes: 7 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
node_modules
dist
coverage
playwright-report
test-results
package-lock.json
project2/api/migrations/meta
1 change: 1 addition & 0 deletions .prettierrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{ "singleQuote": true, "trailingComma": "all" }
9 changes: 9 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# T31 development guide

Read README.md and docs/requirements.md before changing architecture. Project 1 is a static React/Vite app with plain CSS, self-authored components, TanStack Query, live REST data, and Web Storage for preferences/favorite IDs only. Do not connect it to the Project 2 database or cache API resources.

Project 2 foundation lives separately in project2/. Its Node/TypeScript GraphQL API and native PostgreSQL database must run directly on the group VM. No Docker backend/database deployment or hosted Supabase. Move this foundation to the assigned Project 2 repository when that work starts.

Use Node 24 and npm 11; package-lock.json is the installation source of truth. Bun may run scripts. Keep strict TypeScript, validate external data with Zod, infer database types from Drizzle, and regenerate GraphQL types with npm run types:api. Never hand-edit generated.ts or generated migration snapshots.

Use issues, feature branches and teammate-reviewed PRs. Preserve existing changes. Never commit .env or personal contribution logs. Document AI assistance and actual checks. Run npm run check for code changes and relevant Playwright checks for UI changes. Never claim grade A, device testing, deployment, review, or remote publication without evidence.
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Changelog

## 2026-09-11

- Initial Turvær Norge architecture skeleton with one live weather example.
- Separate native PostgreSQL/Node GraphQL foundation for Project 2.
- Typed contracts, developer scripts, tests, requirement traceability and setup docs.

Record post-delivery improvements and responses to feedback here.
10 changes: 10 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
FROM node:24.21.0-bookworm-slim
WORKDIR /app
RUN npm install --global npm@11.11.1
COPY package.json package-lock.json ./
COPY web/package.json web/package.json
COPY project2/api/package.json project2/api/package.json
RUN npm ci
COPY . .
EXPOSE 5173
CMD ["npm", "run", "dev", "--workspace", "@t31/web", "--", "--host", "0.0.0.0"]
133 changes: 117 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,24 +1,125 @@
# T31-Project-1
# Turvær Norge

Repository for team IT2810-H26-T31 in IT2810-H26.
Prosjekt 1 i **IT2810 Webutvikling** ved NTNU.

## Working in this repository
Turvær Norge er en responsiv React-applikasjon som henter oppdaterte værdata for norske byer. Brukeren kan velge aktivitet, sammenligne byer og finne ut hvor været passer best til for eksempel gåtur, sykling eller utendørsaktiviteter.

`main` is protected — you cannot push to it directly. Work on a branch and
open a pull request:
## Kom i gang

Bruk Node **24.6+** og npm **11**. Med nvm:

```bash
git clone --branch dev git@git.ntnu.no:IT2810-H26/T31-Project-1.git
cd T31-Project-1
nvm install
nvm use
npm install --global npm@11.11.1
npm ci
npm run dev
```

Åpne <http://127.0.0.1:5173/project1/>. Uten nvm: installer versjonen i `.node-version` med valgfri Node-versjonsbehandler. Registrer SSH-nøkkelen din på [git.ntnu.no](https://git.ntnu.no/settings/keys) før kloning.

Repoet inneholder foreløpig grunnoppsett og ett [væreksempel for Trondheim](web/src/WeatherExample.tsx). Resten utvikles gjennom [roadmap](roadmap.md). Prosjekt 1 trenger ingen database eller `.env` for å starte.

### Alle npm-kommandoer

| Kommando | Bruk |
| -------------------------- | ----------------------------------------------------- |
| `npm run setup` | Installer avhengigheter, opprett .env, generer typer |
| `npm run env:init` | Opprett .env uten å overskrive eksisterende |
| `npm run dev` | Start frontend |
| `npm run dev:web` | Alias for dev |
| `npm run dev:api` | Start Prosjekt 2-API |
| `npm run dev:all` | Start frontend og API |
| `npm run build` | Bygg frontend til web/dist/ |
| `npm run build:api` | Bygg Node-API |
| `npm run preview` | Forhåndsvis frontendbygget |
| `npm run start:api` | Kjør bygget API |
| `npm run typecheck` | Sjekk all TypeScript |
| `npm run types:api` | Generer GraphQL-typer |
| `npm run types:check` | Sjekk at genererte typer er oppdatert |
| `npm run types:db` | Sjekk databasetyper |
| `npm run db:generate` | Generer SQL-migrasjon |
| `npm run db:migrate` | Kjør migrasjoner |
| `npm run db:seed` | Legg inn lokale eksempeldata |
| `npm run db:reset` | Slett lokale prosjektskjemaer, migrer og seed |
| `npm run db:check` | Sjekk migrasjonsmetadata |
| `npm run lint` | Kjør ESLint |
| `npm run lint:fix` | Rett lint-feil automatisk |
| `npm run format` | Formater med Prettier |
| `npm run format:check` | Sjekk formatering |
| `npm run test` | Kjør Vitest |
| `npm run test:watch` | Vitest i watch-modus |
| `npm run test:coverage` | Mål testdekning |
| `npm run test:e2e` | Kjør Playwright |
| `npm run test:e2e:install` | Installer testnettlesere |
| `npm run test:db` | Sjekk databasetilkobling og lesing |
| `npm run check` | Formatering, lint, typer, migrasjoner, tester og bygg |
| `npm run docker:up` | Bygg/start frontend-container |
| `npm run docker:down` | Stopp frontend-container |
| `npm run docker:logs` | Vis containerlogger |

Du kan også bruke `bun dev`, `bun types:api` og `bun run check`. Installer avhengigheter med `npm ci`; behold én lockfil. Bruk `bun run test` for Vitest, siden `bun test` starter Buns egen testkjører.

## Konsept

Applikasjonen skal:

- hente ferske værdata fra et åpent REST API
- vise værinformasjon for minst 8 norske byer
- la brukeren velge aktivitet
- filtrere og sortere byer etter værforhold
- vise temperatur, nedbør, vind og værtype
- vise tydelig lasting og feilmelding ved API-feil
- fungere på både mobil og desktop

Værdata hentes direkte når applikasjonen brukes og mellomlagres ikke.

## Teknologi

React, TypeScript, Vite, TanStack Query, `fetch`, plain CSS, ESLint, Prettier og Vitest. Eksemplet bruker [Open-Meteo](https://open-meteo.com/en/docs).

Alle UI-komponenter utvikles av gruppen. Prosjektet bruker ikke Bootstrap, Tailwind, Material UI eller andre ferdige UI-komponentbiblioteker.

`project2/` forbereder Node/Hono, GraphQL og native PostgreSQL. Databasekommandoene krever [lokalt PostgreSQL-oppsett](docs/development.md#native-postgresql-setup-for-project-2). `db:reset` sletter lokale prosjektskjemaer. Docker er kun for frontendutvikling; levering skjer via Apache.

## Brancher og commits

Bruk alltid én av typene `fix`, `comment` eller `feature`:

- `fix`: retting av feil.
- `comment`: dokumentasjon eller kodekommentarer.
- `feature`: ny funksjonalitet.

**Branch:** `<type>/<domain>-<details>` — små bokstaver og bindestreker, uten mellomrom eller kolon.

**Commit og PR-tittel:** `<type>(<domain>): <details>`.

| Branch | Commit / PR-tittel |
| ----------------------------------- | ----------------------------------------- |
| `fix/weather-handle-timeout` | `fix(weather): handle request timeout` |
| `comment/docs-setup-guide` | `comment(docs): clarify local setup` |
| `feature/weather-activity-selector` | `feature(weather): add activity selector` |

Eksempel på arbeidsflyt:

```bash
git checkout -b my-feature
git push -u origin my-feature
git switch dev
git pull --ff-only origin dev
git switch -c feature/weather-activity-selector
# Gjør endringene og kjør npm run check.
git add <endrede-filer>
git commit -m "feature(weather): add activity selector"
git push -u origin feature/weather-activity-selector
```

Before a pull request can be merged:
Velg et issue før du starter, og lenk det i PR-en, for eksempel `Closes #8`. Åpne en **Pull request** til `dev`; integrer deretter i beskyttet `main` gjennom review.

- En annen student i IT2810-H26-T31 må godkjenne. Egen godkjenning eller godkjenning fra fagstaben teller ikke.
- Alle review-kommentarer må være løst. Nye commits krever ny godkjenning.
- Ikke push direkte til `main`, force-push delte brancher eller commit `.env` og hemmeligheter.

## Dokumentasjon

1. **A member of IT2810-H26-T31 must approve it.** You cannot approve your own pull
request, and approvals from staff do not count — you review each other's
code.
2. **Every review comment must be marked resolved.** Reply to each one, fix it
or explain why not, then click *Resolve conversation*.
3. **Pushing new commits dismisses the approval**, so if you change something
after being approved, ask for another review. This is deliberate: what was
approved is what gets merged.
[Roadmap](roadmap.md) · [Utviklerguide og planlagt dataflyt](docs/development.md) · [Krav og gjenstående arbeid](docs/requirements.md) · [Tester](docs/testing.md)
10 changes: 10 additions & 0 deletions compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
name: t31-project1
services:
web:
build: .
ports:
- '127.0.0.1:5173:5173'
volumes:
- ./web/src:/app/web/src:ro
- ./web/public:/app/web/public:ro
init: true
104 changes: 104 additions & 0 deletions docs/development.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
# Development reference

The README covers everyday setup. This page contains optional infrastructure commands and deployment details.

## Structure and type safety

- `web/src/WeatherExample.tsx`: the single weather example.
- `web/src/features/weather/`: typed city definitions, Zod response validation and TanStack Query options.
- `web/src/shared/storage.ts`: storage helper for future preferences and favorite city IDs.
- `project2/api/`: independent Node/Hono/GraphQL API with native PostgreSQL and Drizzle migrations.
- `project2/contracts/`: generated resolver/client contracts; regenerate with `npm run types:api`.

Project 1 calls Open-Meteo directly. Wind is requested in m/s, timestamps use Europe/Oslo and precipitation is labelled with the provider's interval. Only the active response is held in memory; weather payloads are never persisted. Future storage features should store preferences and city IDs only.

Project 2 requires GraphQL and a database installed directly on the VM. Hosted Supabase and Docker backend/database deployment do not fit that requirement. Docker here is only an optional frontend development tool; Redis is not needed.

## Native PostgreSQL setup for Project 2

Do this only when working on the optional backend. On Debian/Ubuntu install PostgreSQL directly:

```bash
sudo apt install postgresql postgresql-client
sudo systemctl start postgresql
sudo -u postgres createuser --pwprompt t31_dev
sudo -u postgres createdb --owner=t31_dev t31_project2_dev
npm run env:init
```

Edit `.env` with your chosen password (URL-encode special characters). Do not commit it. Then:

```bash
npm run db:migrate
npm run db:seed
npm run test:db
npm run dev:api
```

Open <http://127.0.0.1:3001/graphql> for development GraphiQL. `/health` reports the process; `/ready` checks the database. Try:

```graphql
query {
notes(first: 10) {
id
body
createdAt
}
}
mutation {
createNote(body: "Our first persisted note") {
id
body
}
}
```

This notes example demonstrates typed persistence and validation; it is not the finished Project 2 catalogue. It has no user authentication or authorization and binds to loopback by default. Before making it publicly writable, design identity/ownership, abuse controls, GraphQL query-cost limits, pagination and domain-specific behavior.

`db:reset` is destructive for its two project schemas. It refuses production mode, non-loopback hosts, URL parameters and database names other than `t31_project2_dev`/`t31_project2_test`. Do not point a loopback tunnel at a remote database. It does not delete other schemas or reset system PostgreSQL. `db:migrate` is intentionally usable on the eventual VM deployment; inspect its target first.

For schema changes: edit `schema.ts`, run `db:generate`, inspect SQL, migrate/reset a dedicated local DB, run `types:api` when SDL changes, and run `check` plus `test:db`. Commit migrations and generated contracts. `db:check` validates migration metadata, not live database drift.

## Apache deployment

Project 1 must be served by Apache on the group VM at `/project1/`. `base: '/project1/'` is already configured. Campus network or NTNU VPN is required to reach the VM. Verify that the assigned hostname is `it2810-31.idi.ntnu.no` before using it.

```bash
npm ci
npm run check
npm run test:e2e
# Set these to the confirmed account/host:
# scp -r web/dist YOUR_NTNU_USER@it2810-31.idi.ntnu.no:~/t31-project1-dist
```

On the VM, install Apache with `sudo apt install apache2`, then copy the **contents** of the built directory into `/var/www/html/project1/` (for example `sudo install -d /var/www/html/project1` followed by `sudo cp -a ~/t31-project1-dist/. /var/www/html/project1/`). Avoid nesting `dist` inside `project1`. Use a fresh staging directory per release; back up any existing deployment before replacing it. Verify `/project1/`, a direct reload, API access, weather loading, keyboard access and console output through Apache. This starter uses no client router, so no SPA rewrite rule is needed.

Project 2's eventual client belongs at `/project2/`. Run its built API on Node, ideally as a systemd service with an environment file, and PostgreSQL directly on the VM. The preferred backend port is 3001. Apache can reverse-proxy `/project2-api/` to `http://127.0.0.1:3001/`; keep the API bound to loopback for that setup. A client then uses `/project2-api/graphql`. Service configuration, final domain, deployment permissions and credentials remain team tasks.

## Planned Project 1 structure

The following diagrams are retained from the team's project plan; these components are not implemented by the skeleton.

## Dataflyt

```mermaid
flowchart LR
A[Brukeren velger aktivitet] --> B[React oppdaterer state]
B --> C[Værtjenesten henter data]
C --> D[Vær-API]
D --> E[Filtrering og sortering]
E --> F[Værkort og detaljvisning]
```

## Komponentflyt

```mermaid
flowchart TD
App --> ActivitySelector
App --> WeatherFilters
App --> WeatherList
WeatherList --> WeatherCard
App --> WeatherDetails
App --> LoadingMessage
App --> ErrorMessage
```
Loading