diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..8ce717d --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,69 @@ +name: Continuous Integration + +on: + push: + branches: [main, ci] + pull_request: + branches: [main] + +permissions: + contents: read + +concurrency: + group: ci-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + cpp: + name: C++ build and unit tests + runs-on: ubuntu-24.04 + steps: + - name: Check out repository + uses: actions/checkout@v4 + - name: Configure CMake + run: cmake -S . -B build -DCMAKE_BUILD_TYPE=Release + - name: Build + run: cmake --build build --parallel + - name: Run unit tests + run: ctest --test-dir build --output-on-failure -C Release + + web: + name: Web API tests and client build + runs-on: ubuntu-24.04 + strategy: + fail-fast: true + matrix: + include: + - name: API + directory: web + command: npm test + - name: Client + directory: client + command: npm run build + steps: + - name: Check out repository + uses: actions/checkout@v4 + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: 20 + - name: Install dependencies + working-directory: ${{ matrix.directory }} + run: npm install --no-audit --no-fund + - name: Run ${{ matrix.name }} validation + working-directory: ${{ matrix.directory }} + run: ${{ matrix.command }} + + mobile: + name: Mobile dependency validation + runs-on: ubuntu-24.04 + steps: + - name: Check out repository + uses: actions/checkout@v4 + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: 20 + - name: Install Expo dependencies + working-directory: mobile + run: npm install --no-audit --no-fund diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..b7762b7 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,38 @@ +name: Release artifacts + +on: + push: + tags: ['v*.*.*'] + workflow_dispatch: + +permissions: + contents: read + +jobs: + package: + name: Build and upload release artifacts + runs-on: ubuntu-24.04 + steps: + - name: Check out repository + uses: actions/checkout@v4 + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: 20 + - name: Install and build web client + working-directory: client + run: npm install --no-audit --no-fund && npm run build + - name: Configure and build C++ service + run: cmake -S . -B build -DCMAKE_BUILD_TYPE=Release && cmake --build build --parallel + - name: Package release bundle + shell: bash + run: | + mkdir -p release/web release/bin + cp -r client/dist release/web/ + cp build/src/wolt_app release/bin/ + tar -czf advancedwolt-${GITHUB_REF_NAME}.tar.gz -C release . + - name: Upload release bundle + uses: actions/upload-artifact@v4 + with: + name: advancedwolt-${{ github.ref_name }} + path: advancedwolt-${{ github.ref_name }}.tar.gz diff --git a/README.md b/README.md index 27a2185..75aaa26 100644 --- a/README.md +++ b/README.md @@ -1,365 +1,136 @@ -# AdvancedWolt โ€“ Exercise 5: Mobile Client & Persistent Data +# AdvancedWolt -This is **Exercise 5**: a full-stack, **multi-client** food-delivery system. It extends the -Exercise 4 React web app with two major additions: +AdvancedWolt is a multi-client food-delivery platform. A MongoDB-backed Express API serves a React web application and a React Native/Expo mobile application, while a C++ TCP service supplies product recommendations. -* **Persistent storage (MongoDB).** The Express API now stores everything in **MongoDB** via - **Mongoose** instead of in-memory arrays, so restaurants, menus, users and orders survive - restarts. Data lives in a Docker volume and is seeded automatically on first boot. -* **A native mobile client (React Native + Expo).** A new `mobile/` app talks to the **same** - Express API as the web client, with **full feature parity** โ€” authentication, restaurant - discovery, search, cart, orders, and restaurant-owner management. +## Features -It builds on the earlier exercises: the **C++ TCP recommendation server (Exercise 2)** powers -"you might also like" suggestions, and the **Node.js + Express REST API (Exercise 3)** is the -single backend serving both clients. +- JWT authentication and protected customer and owner flows +- Restaurant, menu, search, cart, and order management +- Persistent MongoDB storage with idempotent seed data +- Personalized recommendations through the C++ service +- React/Vite web client and Expo mobile client +- Docker Compose stack for the API, web application, recommender, and MongoDB -The assignment is split into two parts: -* **Part A:** Agile project management using JIRA. -* **Part B:** The multi-client architecture โ€” a MongoDB-backed Express API serving a React web - client and a React Native mobile client, with JWT authentication and live (no-mock) data. - -> ๐Ÿ“– **Full build & run walkthrough with screenshots** โ€” see the **[Wiki](wiki/Home.md)**: -> [Architecture Overview](wiki/Architecture-Overview.md), -> [Environment Setup](wiki/Environment-Setup.md) (raise everything with `docker-compose` and -> run **both** the web and mobile clients), [Authentication Flows](wiki/Authentication-Flows.md), -> and [CRUD Flows](wiki/CRUD-Flows.md). - ---- - -## Part A: Agile Workflow (JIRA & GitHub) โ€” *How we worked* - -The development process was strictly managed via JIRA and synchronized with GitHub, adhering to Agile principles: - -* **Epics & User Stories:** The application was divided into logical epics (e.g., Authentication, Ordering, UI/UX) containing specific user stories and actionable tasks. -* **Sprints & Scrum:** The work was organized into sprints. A Scrum Master was appointed to guide sprint planning, and regular status meetings were held (and documented) at least twice a week. -* **Workflow Statuses:** Issues moved through `To Do`, `In Progress`, `Code Review`, and `Done`. Tasks were assigned to members before work began. -* **Blocked Tasks:** Dependencies were explicitly tracked using the `blocked by` link type in JIRA. -* **Feature Branches & Pull Requests:** Every task was developed on a dedicated feature branch named after the JIRA issue (e.g., `AW-12-login-page`). Code was merged to the main branch strictly via Pull Requests, which required approval from other team members before merging. The Jira-GitHub integration automatically linked PRs and branches to their respective JIRA issues. - -**In short:** we plan each task in JIRA (epic โ†’ user story โ†’ task, assigned to an owner -before work starts) โ†’ branch off `main` as `AW--` โ†’ open a Pull Request, which -moves the issue to **Code Review** โ†’ a *different* team member reviews and approves โ†’ merge to -`main` moves the issue to **Done**. Blocking dependencies are tracked with JIRA's `blocked by` -links, and branch/PR names embed the issue key so JIRA links them automatically. - ---- - -## Part B: System Architecture - -The platform is built from **four cooperating components**. Both clients are *thin* โ€” they -hold no mock data; every screen reads and writes live through the same Express REST API, which -persists to MongoDB and consults the C++ recommender. The web client is built into the Express -image and served from the same process; the mobile client runs through Expo and points at the -API via `EXPO_PUBLIC_API_URL`. +## Architecture ```text -โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” -โ”‚ Web client (React) โ”‚ โ”‚ Mobile client โ”‚ -โ”‚ client/ ยท EX4 โ”‚ โ”‚ React Native + Expo โ”‚ -โ”‚ served at :3000 โ”‚ โ”‚ mobile/ ยท EX5 โ”‚ -โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ - โ”‚ HTTP (JSON + JWT Auth) โ”‚ - โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ - โ–ผ -โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” -โ”‚ Express REST API ยท web/ ยท EX3 ยท Node.js โ”‚ -โ”‚ (Validation, Routing, JWT auth, MongoDB via Mongoose) โ”‚ -โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ - โ”‚ TCP socket (newline-delimited) โ”‚ Mongoose - โ–ผ โ–ผ -โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” -โ”‚ C++ Recommendation Server โ”‚ โ”‚ MongoDB โ”‚ -โ”‚ src/ ยท EX2 ยท :8080 โ”‚ โ”‚ mongo:27017 (internal) โ”‚ -โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ +React web (client/) โ”€โ” +Expo mobile (mobile/) โ”œโ”€ HTTP/JSON + JWT โ”€> Express API (web/) โ”€> MongoDB + โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€> C++ recommender (src/, TCP :8080) ``` -| Component | Path | Exercise | Role | -| ----------------- | ---------- | -------- | ------------------------------------------------------------ | -| C++ recommender | `src/` | EX2 | TCP service that logs product views and returns suggestions. | -| Express REST API | `web/` | EX3 | Single backend: validation, JWT auth, MongoDB persistence. | -| Web client | `client/` | EX4 | React SPA, built into and served by the Express image. | -| Mobile client | `mobile/` | EX5 | React Native (Expo) app against the same API. | -| MongoDB | โ€” | EX5 | Document store (Mongoose); data persists in a Docker volume. | - -The data flow is the same for both clients: a client sends an authenticated HTTP request โ†’ the -Express API validates it and reads/writes MongoDB through Mongoose โ†’ when a dish is viewed, the -API opens a TCP socket to the C++ recommender to log the view and fetch related dishes, which -then surface as "you might also like" in the cart. +The web production bundle is built into the web container and served by Express. MongoDB data is stored in the `mongo-data` Compose volume. The mobile app runs separately through Expo and uses `EXPO_PUBLIC_API_URL`. -### Repository Layout +## Requirements -```text -src/ EX2 ยท C++ TCP recommendation server -web/ EX3 ยท Node.js + Express REST API (Mongoose, JWT, seed) โ€” also serves the built web client -client/ EX4 ยท React web client (SPA) -mobile/ EX5 ยท React Native (Expo) mobile client -``` +For the backend and web client, install Docker Desktop with Docker Compose v2. Mobile development additionally requires Node.js 20 or newer and Expo SDK 54 tooling (Expo Go or an Android/iOS runtime). Ports `3000` and `8080` must be available. -#### Backend โ€” `web/src/` - -* **`controllers/`** + **`routes/`** โ€” the REST API (restaurants, products, users, tokens, - orders, search, recommendations). -* **`models/`** + **`models/schemas/`** โ€” Mongoose models and the schemas that validate them. -* **`config/db.js`** โ€” the single, reusable MongoDB connection module every model imports. -* **`services/tcpClient.js`** โ€” the TCP client that talks to the C++ recommender (EX2). -* **`middleware/`** โ€” JWT authentication and request validation. -* **`seed.js`** / **`seedScript.js`** โ€” idempotent demo-data seeding (boot-time and standalone). - -#### Web client โ€” `client/src/` - -* **`pages/`** โ€” route views: `Login` / `Register`, `Home`, `RestaurantDetail`, `Search`, - `Manage` / `ManageAccount`, `Cart` / `Orders` / `OrderDetail`. -* **`components/`** โ€” reusable UI (`Navbar`, `RestaurantCard`, `MenuItem`, `CartLine`, โ€ฆ). -* **`context/`** โ€” `AuthContext` (JWT + user), `ThemeContext` (dark/light), `CartContext`. -* **`routes/`** โ€” `ProtectedRoute` guards for authenticated-only pages. - -#### Mobile client โ€” `mobile/src/` - -A React Native (Expo) app that mirrors the web client against the same API. The drawer is the -phone's take on the web navbar. - -* **`screens/`** โ€” `Login` / `Register`, `Home`, `Restaurant`, `Search`, `Cart`, - `Orders` / `OrderDetail`, `Manage`, `Account`. -* **`navigation/`** โ€” a drawer over a native stack, with `ProtectedScreen` guards mirroring the - web's `ProtectedRoute`. -* **`context/`** โ€” the same `Auth` / `Theme` / `Cart` providers, persisted with AsyncStorage. -* **`api/`** + **`config/api.js`** โ€” the fetch wrapper and the single configurable backend URL - (`EXPO_PUBLIC_API_URL`). - -### Features & In-Depth GUI Walkthrough - -The screenshots below are from the **web client**. Every feature also ships on the **mobile -client** with the same behavior โ€” see the **[Wiki](wiki/Home.md)** for the mobile, -screenshot-backed walkthroughs of each flow. - -1. **Authentication (JWT) & Registration** - * **Sign Up:** Users can register an account by providing a unique username, secure password (requiring at least 8 characters, letters, and digits), a display name, geographic location (X/Y coordinates), and an optional profile image (up to 5MB). The UI features a dynamic image preview and real-time form validation. - * **Login:** Registered users can log in to receive a JWT. The application securely manages this token in the `AuthContext`. - * **Route Protection:** Unauthenticated users can browse restaurants and menus, but attempting to access the shopping cart or order history will automatically redirect them to the Login page. -

- image -image -image - -

- -2. **Home Screen (Restaurant Discovery)** - * **Personalized View:** Upon logging in, the Navbar updates to display the user's name and profile image. - * **Restaurant Listing:** The main dashboard fetches data from the Express backend and displays restaurant cards, distinguishing between "Nearby" and "Promoted" locations. - * **Responsive Design:** Wolt-inspired cards with smooth hover effects and responsive grids. -

- image - -

- -3. **Restaurant Menus & Recommendations** - * **Full Menu:** Clicking a restaurant opens its dedicated page, displaying a grid of available products (dishes) with their prices and descriptions. - * **Smart Recommendations:** When a user views a product, the Node.js server seamlessly communicates with the C++ TCP server (from Exercise 2) to log the view and fetch personalized "Users also viewed" recommendations, which are displayed dynamically on the page. -

- image - image - -

- -4. **Shopping Cart & Checkout** - * **Cart Management:** Users can add multiple products from a restaurant to their shopping cart. A persistent cart context tracks the selected items. - * **Real-time Totals:** The cart instantly recalculates sub-totals and allows the user to increment, decrement, or remove items before proceeding to checkout. - * **Placing Orders:** A single click sends the order payload to the backend, which creates a new pending order attached to the user's account. - image - -5. **Order Management & History** - * **Tracking Orders:** The "My Orders" dashboard allows logged-in users to review all their past and active orders. - * **Order Details & Status Updates:** Users can view the itemized receipt for any specific order and change its status (e.g., from `pending` to `completed`) using a simple, intuitive interface that PATCHes the backend. -

- image - -

- -6. **Search Functionality** - * **Global Search:** A dedicated search bar in the Navbar allows users to query the entire platform. - * **Granular Results:** The search results page dynamically categorizes matches, showing matching restaurants alongside individual dishes whose name or description contains the query. -

- image - -

- -7. **Dynamic Theming (Light/Dark Mode)** - * **Instant Switch:** The Navbar includes a moon/sun toggle icon that instantly switches the application between `light mode` and `dark mode`. - * **Global Application:** This toggles CSS variables globally across all components, instantly re-coloring backgrounds, text, and borders for a comfortable viewing experience without reloading the page. -

- image - -

- -8. **Mobile client (React Native + Expo) โ€” full feature parity** - * All of the above flows โ€” JWT auth & registration, restaurant discovery (Near you / - Promoted / per-category), restaurant menus, **cart with C++-powered recommendations**, - checkout, orders & order detail, global search, profile management, and dark/light theming - โ€” are reimplemented natively in `mobile/`. - * The drawer replaces the web navbar; owner-only **Manage** is gated to restaurant owners; - state and auth persist across restarts via AsyncStorage. - * **Screenshot walkthroughs for the mobile client live in the - [Wiki](wiki/Home.md):** [Environment Setup](wiki/Environment-Setup.md), - [Authentication Flows](wiki/Authentication-Flows.md), and [CRUD Flows](wiki/CRUD-Flows.md). - ---- - -## Running the Application - -The entire stack is containerized using Docker Compose. - -### Prerequisites (short version) - -- **Docker Desktop** with **Compose v2** (the `docker compose` command) โ€” the only thing needed - for the backend + web client. No local Node, C++ compiler, or MongoDB required. -- **Node.js 20 LTS+** and a mobile runtime โ€” *only* if you run the mobile app. Easiest is a - phone with the **Expo Go** app (supporting **Expo SDK 54**); an **Android emulator** also - works. Pinned toolchain: Node 20, MongoDB 7, Expo SDK 54, React Native 0.81, React 19. -- Host ports **3000** and **8080** must be free (MongoDB's 27017 stays internal). No `.env` or - secrets are needed for the backend. - -> ๐Ÿ“‹ **Full, bulletproof prerequisites** โ€” exact versions, toolchain verification commands, and -> the two mobile-runtime paths โ€” are in the -> **[Wiki โ†’ Environment Setup](wiki/Environment-Setup.md#0-prerequisites)**. - -### Running the full system (web **and** mobile) โ€” TL;DR - -There are **two clients** against one backend. Run them in this order: +## Quick start ```bash -# 1) Backend + web client (C++ recommender, MongoDB, Express API, built React web app) -# From the repo root: docker compose up --build -# โ†’ Web client: http://localhost:3000 -# โ†’ REST API: http://localhost:3000/api - -# 2) Mobile client (React Native + Expo) โ€” in a second terminal, after the backend is up: -cd mobile -npm install -npm run android # or: npx expo start โ†’ press a, or scan the QR in Expo Go ``` -The mobile app reads the API base URL from `EXPO_PUBLIC_API_URL`, defaulting to -`http://10.0.2.2:3000` (Android emulator โ†’ host). For a **physical phone**, point it at your -computer's LAN IP, e.g. `EXPO_PUBLIC_API_URL=http://192.168.1.20:3000 npx expo start`. +Open . The REST API is available under `/api`. Stop the stack with `Ctrl+C`, or run `docker compose down`. -The detailed, screenshot-backed version of this is in the -**[Wiki โ†’ Environment Setup](wiki/Environment-Setup.md)**. +To run the mobile client, keep the Compose stack running and use a second terminal: -### Quick Start (Docker Compose) +```bash +cd mobile +npm install +npm run android # or: npm run ios / npm run web +``` -From the root of the project, run: +Android emulators use `http://10.0.2.2:3000` by default. For a physical device, set the computer's LAN address before starting Expo: ```bash -docker compose up --build +EXPO_PUBLIC_API_URL=http://192.168.1.20:3000 npx expo start ``` -

- image - -

+## Configuration -This starts the backend stack: -1. **`cpp-service`**: The Exercise 2 C++ server on port 8080. -2. **`mongo`**: A MongoDB instance available to the other Compose services as - `mongo:27017`. Its data is stored in the named Docker volume `mongo-data`, - so it **survives container restarts** (`docker compose down` followed by - `docker compose up` keeps your data). MongoDB is not published to the host, - which avoids conflicts with any local MongoDB already using port 27017. -3. **`web`**: The Express API backend on port 3000. It connects to MongoDB through Mongoose on boot, seeds an empty database, and serves the built React web client from the same process. +The Compose stack supplies `PORT`, `MONGO_URI`, `CPP_SERVICE_HOST`, and `CPP_SERVICE_PORT` to the API. Local API configuration may use the same variables. Do not commit `.env` files or credentials. The mobile API URL is read from `EXPO_PUBLIC_API_URL`. -Once the containers are running, open your browser to: -**[http://localhost:3000](http://localhost:3000)** +## Development commands -API endpoints are available under **[http://localhost:3000/api](http://localhost:3000/api)**. +### C++ service -### Mobile app against the Docker stack +```bash +cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug +cmake --build build --parallel +ctest --test-dir build --output-on-failure +``` -The mobile app is not containerized; run it with Expo after the stack above is -up. The app reads the API base URL from `EXPO_PUBLIC_API_URL`, defaulting to -`http://10.0.2.2:3000` for the Android emulator. +### Express API ```bash -cd mobile +cd web npm install -npm run android +npm test +npm start ``` -For a physical device, point Expo at the host machine's LAN IP: +The API tests validate Mongoose schemas in memory and do not require MongoDB. `npm run seed` seeds a running database explicitly. + +### React web client ```bash -EXPO_PUBLIC_API_URL=http://:3000 npx expo start +cd client +npm install +npm run dev +npm run build +npm run preview ``` -Keep `node_modules` local; it is intentionally ignored and must not be -committed. A minimal end-to-end smoke check is: - -1. Run `docker compose up --build` and wait for the API to log its MongoDB - connection and seed completion. -2. Launch the mobile app with the base URL pointing at the API. -3. Confirm the Home feed shows seeded restaurants. -4. Log in or register, then open a protected screen to confirm JWT-backed auth - works against MongoDB-backed data. +### Mobile client -### Database connection (MongoDB / Mongoose) +```bash +cd mobile +npm install +npm start +``` -The Node server persists data in MongoDB. The connection is centralized in a single -reusable module, **`web/src/config/db.js`**, which every Mongoose model imports. +The mobile package currently provides Expo start targets but no automated test or production build script. -* **`MONGO_URI`** โ€” the connection string, read from the environment so **no - connection string or secret is ever committed**. Docker Compose sets it to - `mongodb://mongo:27017/wolt`. When running the server outside Docker it defaults to - `mongodb://localhost:27017/wolt`. The default URI carries no credentials. -* On boot the server connects via Mongoose, logs `Connected to MongoDB at โ€ฆ`, and - **fails fast** (logs a readable error and exits) if MongoDB is unreachable. +## Testing and CI -Every controller reads and writes through Mongoose models (`web/src/models/*.js`, -backed by the schemas in `web/src/models/schemas/`); no data is kept in in-memory -arrays. The HTTP API is unchanged โ€” the same response bodies and status codes the -EX4 web client and the mobile app expect. +Every pull request targeting `main` and pushes to `main` or `ci` run `.github/workflows/ci.yml`. It installs clean dependencies, builds and tests the C++ service, runs the API test suite, builds the web client, and validates mobile dependencies. Jobs use Node.js 20 and dependency caching where supported. -### Seeding the database +## Releases -On boot the server seeds an empty database with demo restaurants, menus, users and -orders (the seed is idempotent: it skips when restaurants already exist, so data in -the `mongo-data` volume is never duplicated). To seed a fresh database without -starting the API, run the standalone script: +Pushing a semantic version tag such as `v5.1.0`, or starting the **Release artifacts** workflow manually, builds the C++ service and React web client and uploads a tarball artifact. The workflow does not deploy to an external service or publish an image; deployment remains an operator-controlled Docker Compose step. ```bash -cd web -npm install -npm run seed # connects to MONGO_URI, seeds if empty, then exits +git tag v5.1.0 +git push origin v5.1.0 ``` -### Demo accounts (for graders) +## Repository structure + +```text +src/ C++ TCP recommendation service +tests/ C++ unit tests +web/ Express REST API, Mongoose models, and API tests +client/ React/Vite web client +mobile/ React Native/Expo client +wiki/ Architecture and environment walkthroughs +``` -The seed creates ready-to-use logins, so you can exercise every flow without -registering. **No setup beyond `docker compose up` is required** โ€” these exist as -soon as the database is seeded. +## Troubleshooting -| Role | Username | Password | What you can do | -| ---------------- | --------------------------------------- | ----------- | ---------------------------------------------------------------------------------------------------- | -| Restaurant owner | `wolt-partners` | `Partners1` | Owns **all seeded restaurants** โ€” open **Manage** to create, edit and delete restaurants and dishes. | -| Customer | `noa` (also `amir`, `maya`, `daniel`, โ€ฆ) | `Password1` | Browse, search, add to cart, place and manage orders. | +- If startup fails, confirm Docker is running and ports `3000` and `8080` are free. +- If MongoDB data is stale during local development, `docker compose down -v` removes the named data volume; the next start reseeds it. +- A physical phone must reach the host over the LAN; use the host LAN IP in `EXPO_PUBLIC_API_URL`, and allow port `3000` through the local firewall. +- For detailed screenshots and flow documentation, see the [wiki](wiki/Home.md), including [environment setup](wiki/Environment-Setup.md) and [architecture](wiki/Architecture-Overview.md). -> **To test restaurant management** (web *or* mobile), log in as -> **`wolt-partners` / `Partners1`**. It owns the entire seeded catalog, so the -> **Manage** screen opens pre-filled and ready to edit. On **mobile**, the -> **Manage** drawer item only appears for restaurant owners. You can also register -> a new **Restaurant owner** account to see the create-from-empty flow. +## Contributing -### Tests +Create a focused branch from `main`, make the smallest change that solves the issue, run the commands above, and open a pull request. Keep secrets and generated build output out of commits. Pull requests must pass the CI workflow before review. -```bash -cd web -npm install -npm test # runs the Mongoose schema validation tests (no database required) -``` +## Security -The schema tests (`web/tests/models.test.js`) validate the domain models in memory -via `validateSync()` and need no MongoDB connection. End-to-end CRUD is verified -against the running stack โ€” bring the system up with `docker compose up` and use -`tests.ps1` (an HTTP smoke script against `http://localhost:3000`). +Use strong, unique credentials for local accounts and keep JWT/database configuration out of source control. Report suspected vulnerabilities privately to the repository maintainers rather than opening a public issue with exploit details. +## License +This project is distributed under the [ISC license](https://opensource.org/license/isc-license-txt/).