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
16 changes: 11 additions & 5 deletions backend/deploy/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
Mal for å kjøre GraphQL-backenden som egen systemd-tjeneste på
`it2810-36.idi.ntnu.no`. Steg-for-steg på VM: [docs/vm-backend.md §7](../../docs/vm-backend.md#7-graphql-med-systemd-port-3001).

**Verifisert på VM (oktober 2026):** tjenesten kjører som `User=birkjr`,
`Group=eall_s`, med Node
`/home/birkjr/.nvm/versions/node/v24.21.0/bin/node`,
`WorkingDirectory=/home/birkjr/T36-Project-2/backend`, miljø fra
**Verifisert på VM (oktober 2026):** tjenesten kjører som
`User=<NTNU_BRUKERNAVN>`, `Group=eall_s` (primærgruppe på IT2810-VM), med Node
fra nvm (f.eks. `~/.nvm/versions/node/v24.21.0/bin/node`),
`WorkingDirectory=~/T36-Project-2/backend`, miljø fra
`/etc/t36-project2/backend.env`. GraphQL svarer på `127.0.0.1:3001/graphql`
(`health`, `listings`, `createListing`); `systemctl restart` og `enabled` er
testet. VM-reboot er ikke testet.
Expand Down Expand Up @@ -77,15 +77,21 @@ prosessen, men ikke for «alle» på VM:

```bash
export DEPLOY_USER="<NTNU_BRUKERNAVN>"
# Samme gruppe som `Group=` i systemd-enheten (på VM ofte primærgruppen, f.eks. eall_s).
export DEPLOY_GROUP="$(id -gn "${DEPLOY_USER}")"

sudo mkdir -p /etc/t36-project2
sudo cp "/home/${DEPLOY_USER}/T36-Project-2/backend/deploy/backend.env.example" \
/etc/t36-project2/backend.env
sudo nano /etc/t36-project2/backend.env # DATABASE_URL, HOST, PORT
sudo chmod 640 /etc/t36-project2/backend.env
sudo chown "root:${DEPLOY_USER}" /etc/t36-project2/backend.env
sudo chown "root:${DEPLOY_GROUP}" /etc/t36-project2/backend.env
```

Med `640` kan prosessen lese filen når tjenesten kjører som `User=${DEPLOY_USER}` og
`Group=${DEPLOY_GROUP}`. Hvis `Group=` i unit-filen avviker fra `DEPLOY_GROUP`, juster
enten `chown` eller `Group=` slik at de stemmer.

**Krav i filen:** `HOST=127.0.0.1`, `PORT=3001`. GraphQL-implementasjonen må respektere
disse.

Expand Down
1 change: 1 addition & 0 deletions backend/src/db/listingsQuery.test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/** Enhetstester for SQL-bygging i listingsQuery. */
import { describe, expect, it } from 'vitest';

import type { ListingFilter } from '../validation/listingFilterArgs.js';
Expand Down
1 change: 1 addition & 0 deletions backend/src/db/listingsQuery.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/** Bygger WHERE- og ORDER BY-deler for listings-spørringer (parameterisert SQL). */
import type {
ListingFilter,
ListingSort,
Expand Down
1 change: 1 addition & 0 deletions backend/src/db/listingsRepository.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/** PostgreSQL-tilgang for listings: side, enkelt rad, områder og insert. */
import { randomUUID } from 'node:crypto';

import type { Listing, ListingRow } from '../types/listing.js';
Expand Down
1 change: 1 addition & 0 deletions backend/src/graphql/graphql.api.test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/** Integrasjonstester for health, listing, createListing og listingAreas. */
import type { ApolloServer } from '@apollo/server';
import { describe, it, expect, beforeAll, afterAll, afterEach } from 'vitest';

Expand Down
1 change: 1 addition & 0 deletions backend/src/graphql/listingsFilter.api.test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/** API-tester for listings med søk, filtre og sortering. */
import type { ApolloServer } from '@apollo/server';
import { afterAll, beforeAll, describe, expect, it } from 'vitest';

Expand Down
1 change: 1 addition & 0 deletions backend/src/graphql/listingsPagination.api.test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/** API-tester for paginerte listings-spørringer. */
import type { ApolloServer } from '@apollo/server';
import { afterAll, beforeAll, describe, expect, it } from 'vitest';

Expand Down
1 change: 1 addition & 0 deletions backend/src/graphql/resolvers.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/** GraphQL resolvere — kobler spørringer og mutasjoner til repository og validering. */
import { GraphQLError } from 'graphql';

import {
Expand Down
1 change: 1 addition & 0 deletions backend/src/graphql/schema.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/** GraphQL typeDefs for annonser, vurderinger, paginering, filtre og mutasjoner. */
export const typeDefs = `#graphql
enum ToolCategory {
powerTools
Expand Down
1 change: 1 addition & 0 deletions backend/src/scripts/seed.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/** Idempotent seed av de ti faste eksempelannonsene i listings. */
import { pool } from '../db/pool.js';
import { seedListings } from '../seed/listings.js';
import { seedReviews } from '../seed/reviews.js';
Expand Down
1 change: 1 addition & 0 deletions backend/src/seed/generateListings.test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/** Enhetstester for deterministisk generateListings. */
import { describe, expect, it } from 'vitest';

import {
Expand Down
1 change: 1 addition & 0 deletions backend/src/server.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/** Starter Apollo Server (GraphQL) med HOST/PORT fra miljø. */
import 'dotenv/config';

import { ApolloServer } from '@apollo/server';
Expand Down
1 change: 1 addition & 0 deletions backend/src/test/apolloTestServer.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/** Apollo Server-instans for GraphQL API-tester (Vitest). */
import type { ApolloServer } from '@apollo/server';

export type TestApolloServer = ApolloServer;
Expand Down
1 change: 1 addition & 0 deletions backend/src/test/env.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/** Laster test-miljø og sikrer at DATABASE_URL peker på *_test-database. */
import {
assertAllowedTestDatabaseUrl,
isAllowedTestDatabaseName,
Expand Down
1 change: 1 addition & 0 deletions backend/src/test/listingExpectations.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/** Felles Vitest-hjelpere for å asserte listing-felter i API-tester. */
import { expect } from 'vitest';

const TOOL_CATEGORIES = [
Expand Down
1 change: 1 addition & 0 deletions backend/src/test/testDatabaseUrl.test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/** Enhetstester for testDatabaseUrl-hjelpere. */
import { describe, it, expect } from 'vitest';

import {
Expand Down
1 change: 1 addition & 0 deletions backend/src/validation/createListingInput.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/** Validerer createListing-input (speiler frontend listingForm-grenser). */
import { GraphQLError } from 'graphql';

import type { ToolCategory } from '../types/listing.js';
Expand Down
1 change: 1 addition & 0 deletions backend/src/validation/listingFilterArgs.test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/** Enhetstester for listingFilterArgs-validering. */
import { GraphQLError } from 'graphql';
import { describe, expect, it } from 'vitest';

Expand Down
1 change: 1 addition & 0 deletions backend/src/validation/listingFilterArgs.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/** Parser og validerer filter- og sorteringsargumenter for listings. */
import { GraphQLError } from 'graphql';

import type { ToolCategory, ToolCondition } from '../types/listing.js';
Expand Down
1 change: 1 addition & 0 deletions backend/src/validation/paginationArgs.test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/** Enhetstester for paginationArgs-validering. */
import { GraphQLError } from 'graphql';
import { describe, expect, it } from 'vitest';

Expand Down
1 change: 1 addition & 0 deletions backend/src/validation/paginationArgs.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/** Validerer limit/offset for paginerte listings-spørringer. */
import { GraphQLError } from 'graphql';

/** Antall annonser per side når klienten ikke ber om noe annet. */
Expand Down
18 changes: 18 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"@testing-library/jest-dom": "^7.0.1",
"@testing-library/react": "^16.3.3",
"@testing-library/user-event": "^14.6.7",
"@types/node": "^24.10.1",
"@types/react": "^19.3.0",
"@types/react-dom": "^19.3.0",
"@vitejs/plugin-react": "^6.1.1",
Expand Down
13 changes: 6 additions & 7 deletions src/data/mockListings.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
/**
* Oppdiktede eksempelannonser for prototypen. Ingen av annonsene er ekte
* tilbud, og ingen personopplysninger er brukt. Illustrasjonene er laget for
* prosjektet.
* Ti faste eksempelannonser for Vitest, `listingMocks` og designsiden
* (`design.html`). Produksjon og appen henter data fra GraphQL. Innholdet
* speiler seed i backend og dekker gratis/betalt utlån, varierende titler og
* annonser uten bilde.
*
* Dataene er valgt for å dekke ulike tilfeller i visningene: gratis og betalt
* utlån, korte og lange titler, tomt tilbehør og annonser uten bilde.
* Snittscore og antall vurderinger er de samme som eksempelvurderingene i
* backend/src/seed/reviews.ts gir, og noen annonser har ingen vurderinger.
*
* Datakilden erstattes senere av GraphQL-backenden. Komponenter bør derfor få
* annonser gjennom props i stedet for å importere denne filen direkte.
* Sider og komponenter skal ikke importere denne filen direkte — bruk props
* eller mockede GraphQL-svar.
*/

import type { Listing } from '../types/listing.ts';
Expand Down
1 change: 1 addition & 0 deletions src/design/DesignPreview.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/** Designreferanse: komponenter og mock-annonser for design.html. */
import Button from '../components/Button/Button.tsx';
import ListingGrid from '../components/ListingGrid/ListingGrid.tsx';
import PriceTag from '../components/PriceTag/PriceTag.tsx';
Expand Down
1 change: 1 addition & 0 deletions src/design/main.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/** Entry for design.html — viser komponenter og mock-annonser, ikke med i build. */
import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import { MemoryRouter } from 'react-router';
Expand Down
1 change: 1 addition & 0 deletions src/pages/CatalogPage/CatalogPage.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/** Katalog med server-side søk, filtre, sortering og paginering via GraphQL. */
import { useQuery } from '@apollo/client/react';
import { useCallback, useEffect, useRef } from 'react';
import { Link, useSearchParams } from 'react-router';
Expand Down
1 change: 1 addition & 0 deletions src/pages/ListingDetailPage/ListingDetailPage.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/** Detaljvisning for én annonse og leieforespørsel (demo). */
import { useQuery } from '@apollo/client/react';
import { Link, useLocation, useParams } from 'react-router';
import ListingImage from '../../components/ListingImage/ListingImage.tsx';
Expand Down
1 change: 1 addition & 0 deletions src/pages/NotFoundPage/NotFoundPage.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/** Side for ukjente ruter, med lenke tilbake til katalogen. */
import { Link } from 'react-router';
import { usePageTitle } from '../../hooks/usePageTitle.ts';

Expand Down
2 changes: 1 addition & 1 deletion src/pages/RentOutPage/RentOutPage.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/** Skjema for å opprette nye annonser via GraphQL createListing. */
import ListingForm from '../../components/ListingForm/ListingForm.tsx';
import { usePageTitle } from '../../hooks/usePageTitle.ts';

/** Siden der brukere legger ut egne verktøy for utleie eller gratis utlån. */
function RentOutPage() {
usePageTitle('Lei ut verktøy');

Expand Down
4 changes: 2 additions & 2 deletions src/types/listing.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
/**
* Felles datatype for en verktøyannonse.
*
* Kategori og tilstand er faste engelske nøkler slik at de senere kan bli
* GraphQL-enums. Norske visningsnavn ligger i utils/listingFormat.ts.
* Kategori og tilstand er faste engelske nøkler, i tråd med GraphQL-enums.
* Norske visningsnavn ligger i utils/listingFormat.ts.
*/

export type ToolCategory =
Expand Down
1 change: 1 addition & 0 deletions tsconfig.node.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
"target": "ES2023",
"lib": ["ES2023"],
"types": ["node"],
"module": "ESNext",
"skipLibCheck": true,

Expand Down