profileShare

rasmusjy / tasteprint

Read-only snapshot

No repository description.

main default branch 169 files Expires Sep 13, 2026, 9:06 AM
README.md 5,409 bytes
1 # Tasteprint
2
3 Tasteprint is a travel food passport. Users record dishes they have tried, see which parts of a food culture they have covered, receive a five-bite mission for an upcoming trip, and compare or combine their map with friends.
4
5 The product measures cultural breadth instead of restaurant visits. Each destination starts with six entry points: staple, street food, breakfast, sweet, drink, and signature dish. Importance weights keep a famous or defining dish more meaningful than a secondary discovery.
6
7 ## What is included
8
9 - Account registration, login, opaque bearer sessions, logout, editable profiles, and verified account deletion
10 - A curated atlas of 12 destinations and 72 dishes
11 - Tasting journal with ratings, notes, dates, places, coordinates, and validated photo uploads
12 - Weighted world and destination coverage
13 - Important missing dishes based on the user's current map and next trip
14 - Trips with a persisted five-bite mission and date-aware completion
15 - Shared destination challenges with invite codes and group progress
16 - Public Tasteprint pages with privacy controls
17 - Two-person taste map comparison and a suggested shared bite
18 - Responsive desktop and mobile interfaces
19 - OpenAPI documentation, health probes, Docker deployment, and CI
20
21 ## Architecture
22
23 ```text
24 Browser
25 |
26 v
27 Nginx, React single-page application
28 |
29 +---- /api and /uploads
30 |
31 v
32 Spring Boot modular monolith
33 | | |
34 v v v
35 PostgreSQL file media health and OpenAPI
36 ```
37
38 The backend is a modular monolith. Account, catalog, tasting, journey, progress, media, social, and demo data are separate Java packages with verified Spring Modulith boundaries. This keeps deployment and transactions simple while preserving service boundaries that can be extracted later if scale requires it.
39
40 See [Architecture](docs/ARCHITECTURE.md) for module ownership, request flows, security choices, and the reasons for not starting with microservices.
41
42 ## Stack
43
44 | Area | Technology |
45 | --- | --- |
46 | Backend | Java 21, Spring Boot 3.5, Spring Security, Spring Data JPA |
47 | Architecture | Spring Modulith |
48 | Database | PostgreSQL 17, Flyway migrations, H2 for fast integration tests |
49 | Frontend | React 19, TypeScript 5.9, Vite, TanStack Query, React Router |
50 | Map | D3 Geo, TopoJSON, Natural Earth data through world-atlas |
51 | Testing | JUnit 5, MockMvc, Testcontainers, Vitest, Testing Library |
52 | Delivery | Docker Compose, Nginx, GitHub Actions |
53
54 ## Run with Docker
55
56 Requirements: Docker Desktop or Docker Engine with Compose.
57
58 ```bash
59 cp .env.example .env
60 docker compose up --build
61 ```
62
63 Open:
64
65 - Application: `http://localhost:3000`
66 - API documentation: `http://localhost:8080/docs`
67 - Backend readiness: `http://localhost:8080/actuator/health/readiness`
68
69 The local demo account is:
70
71 ```text
72 Email: demo@tasteprint.app
73 Password: tasteprint
74 ```
75
76 Set `DEMO_DATA_ENABLED=false` before a public deployment. Replace the sample database password in `.env` with a generated secret.
77
78 ## Run for development
79
80 Start the backend. No local database is required because development defaults to a file-backed H2 database in PostgreSQL compatibility mode.
81
82 ```powershell
83 cd backend
84 .\mvnw.cmd spring-boot:run
85 ```
86
87 In another terminal:
88
89 ```powershell
90 cd frontend
91 npm install
92 npm run dev
93 ```
94
95 Vite serves the interface at `http://localhost:5173` and proxies API and upload requests to port 8080.
96
97 ## Tests
98
99 Backend tests cover authentication, validation, privacy, ownership, tasting CRUD, paging, trip missions, shared challenge progress, media validation, CORS, module boundaries, and application startup.
100
101 ```powershell
102 cd backend
103 .\mvnw.cmd verify
104 ```
105
106 The PostgreSQL compatibility test runs automatically when Docker is available and skips cleanly when it is not.
107
108 Frontend tests cover the API client, expired sessions, protected routing, date behavior, and formatting. The production build also performs strict TypeScript checking.
109
110 ```powershell
111 cd frontend
112 npm test
113 npm run lint
114 npm run build
115 ```
116
117 ## Configuration
118
119 | Variable | Purpose | Local default |
120 | --- | --- | --- |
121 | `DB_URL` | JDBC database URL | File-backed H2 |
122 | `DB_USER` | Database user | `sa` |
123 | `DB_PASSWORD` | Database password | Empty |
124 | `APP_ALLOWED_ORIGINS` | Comma-separated browser origins | Local frontend ports |
125 | `MEDIA_DIRECTORY` | Photo storage path | `./uploads` |
126 | `DEMO_DATA_ENABLED` | Seed demo accounts and activity | `true` |
127 | `PORT` | Backend HTTP port | `8080` |
128
129 ## Product rules
130
131 - A dish counts toward a user's global Tasteprint wherever it was eaten.
132 - A dish counts toward a trip only when the tasting country and date match that trip.
133 - A challenge combines member dishes logged within its date range. This allows both travel groups and local tasting clubs.
134 - Coverage is weighted by cultural importance and means breadth, not expertise.
135 - Public pages are private by default and never expose email addresses, exact coordinates, restaurant details, or internal timestamps.
136 - Uploaded files are limited to 6 MB, checked by MIME type and file signature, bound to their owner, and removed with their last tasting or account.
137
138 The catalog is intentionally stored as reviewed migration data, not copied blindly from a third-party popularity feed. Adding a destination means adding six balanced cultural entry points with an explanation of why each matters.
139