diff --git a/README.md b/README.md index 658189a..55293de 100644 --- a/README.md +++ b/README.md @@ -1,261 +1,142 @@ # The Biergarten App -A social platform for craft beer enthusiasts to discover breweries, share reviews, and -connect with fellow beer lovers. +The Biergarten App is a multi-project monorepo with a .NET backend and an active React +Router frontend in `src/Website`. The current website focuses on account flows, theme +switching, shared UI components, Storybook coverage, and integration with the API. -**Documentation** +## Documentation -- [Getting Started](docs/getting-started.md) - Setup and installation -- [Architecture](docs/architecture.md) - System design and patterns -- [Database](docs/database.md) - Schema and stored procedures -- [Docker Guide](docs/docker.md) - Container deployment -- [Testing](docs/testing.md) - Test strategy and commands -- [Environment Variables](docs/environment-variables.md) - Configuration reference +- [Getting Started](docs/getting-started.md) - Local setup for backend and active website +- [Architecture](docs/architecture.md) - Current backend and frontend architecture +- [Docker Guide](docs/docker.md) - Container-based backend development and testing +- [Testing](docs/testing.md) - Backend and frontend test commands +- [Environment Variables](docs/environment-variables.md) - Active configuration reference +- [Token Validation](docs/token-validation.md) - JWT validation architecture +- [Legacy Website Archive](docs/archive/legacy-website-v1.md) - Archived notes for the old Next.js frontend -**Diagrams** +## Diagrams -- [Architecture](docs/diagrams/pdf/architecture.pdf) - Layered architecture -- [Deployment](docs/diagrams/pdf/deployment.pdf) - Docker topology -- [Authentication Flow](docs/diagrams/pdf/authentication-flow.pdf) - Auth sequence -- [Database Schema](docs/diagrams/pdf/database-schema.pdf) - Entity relationships +- [Architecture](docs/diagrams-out/architecture.svg) - Layered architecture +- [Deployment](docs/diagrams-out/deployment.svg) - Docker topology +- [Authentication Flow](docs/diagrams-out/authentication-flow.svg) - Auth sequence +- [Database Schema](docs/diagrams-out/database-schema.svg) - Entity relationships -## Project Status +## Current Status -**Active Development** - Transitioning from full-stack Next.js to multi-project monorepo +Active areas in the repository: -- Core authentication and user management APIs -- Database schema with migrations and seeding -- Layered architecture (Domain, Service, Infrastructure, Repository, API) -- Comprehensive test suite (unit + integration) -- Frontend integration with .NET API (in progress) -- Migration from Next.js serverless functions +- .NET 10 backend with layered architecture and SQL Server +- React Router 7 website in `src/Website` +- Shared Biergarten theme system with a theme guide route +- Storybook stories and browser-based checks for shared UI +- Auth demo flows for home, login, register, dashboard, logout, and confirmation +- Toast-based feedback for auth outcomes ---- +Legacy area retained for reference: + +- `src/Website-v1` contains the archived Next.js frontend and is no longer the active website ## Tech Stack -**Backend**: .NET 10, ASP.NET Core, SQL Server 2022, DbUp **Frontend**: Next.js 14+, -TypeScript, TailwindCSS **Testing**: xUnit, Reqnroll (BDD), FluentAssertions, Moq -**Infrastructure**: Docker, Docker Compose **Security**: Argon2id password hashing, JWT -(HS256) - ---- +- **Backend**: .NET 10, ASP.NET Core, SQL Server 2022, DbUp +- **Frontend**: React 19, React Router 7, Vite 7, Tailwind CSS 4, DaisyUI 5 +- **UI Documentation**: Storybook 10, Vitest browser mode, Playwright +- **Testing**: xUnit, Reqnroll (BDD), FluentAssertions, Moq +- **Infrastructure**: Docker, Docker Compose +- **Security**: Argon2id password hashing, JWT access/refresh/confirmation tokens ## Quick Start -### Prerequisites - -- [.NET SDK 10+](https://dotnet.microsoft.com/download) -- [Docker Desktop](https://www.docker.com/products/docker-desktop) -- [Node.js 18+](https://nodejs.org/) (for frontend) - -### Start Development Environment +### Backend ```bash -# Clone repository git clone https://github.com/aaronpo97/the-biergarten-app cd the-biergarten-app - -# Configure environment cp .env.example .env.dev - -# Start all services docker compose -f docker-compose.dev.yaml up -d - -# View logs -docker compose -f docker-compose.dev.yaml logs -f ``` -**Access**: +Backend access: -- API: http://localhost:8080/swagger -- Health: http://localhost:8080/health +- API Swagger: http://localhost:8080/swagger +- Health Check: http://localhost:8080/health -### Run Tests +### Frontend ```bash -docker compose -f docker-compose.test.yaml up --abort-on-container-exit +cd src/Website +npm install +API_BASE_URL=http://localhost:8080 SESSION_SECRET=dev-secret npm run dev ``` -Results are in `./test-results/` +Optional frontend tools: ---- +```bash +cd src/Website +npm run storybook +npm run test:storybook +npm run test:storybook:playwright +``` ## Repository Structure +```text +src/Core/ Backend projects (.NET) +src/Website/ Active React Router frontend +src/Website-v1/ Archived legacy Next.js frontend +docs/ Active project documentation +docs/archive/ Archived legacy documentation ``` -src/Core/ # Backend (.NET) -├── API/ -│ ├── API.Core/ # ASP.NET Core Web API -│ └── API.Specs/ # Integration tests (Reqnroll) -├── Database/ -│ ├── Database.Migrations/ # DbUp migrations -│ └── Database.Seed/ # Data seeding -├── Domain.Entities/ # Domain models -├── Infrastructure/ # Cross-cutting concerns -│ ├── Infrastructure.Jwt/ -│ ├── Infrastructure.PasswordHashing/ -│ ├── Infrastructure.Email/ -│ ├── Infrastructure.Repository/ -│ └── Infrastructure.Repository.Tests/ -└── Service/ # Business logic - ├── Service.Auth/ - ├── Service.Auth.Tests/ - └── Service.UserManagement/ - -Website/ # Frontend (Next.js) -docs/ # Documentation -docs/diagrams/ # PlantUML diagrams -``` - ---- ## Key Features -### Implemented +Implemented today: -- User registration and authentication -- JWT token-based auth -- Argon2id password hashing -- SQL Server with stored procedures -- Database migrations (DbUp) -- Docker containerization -- Comprehensive test suite -- Swagger/OpenAPI documentation -- Health checks +- User registration and login against the API +- JWT-based auth with access, refresh, and confirmation flows +- SQL Server migrations and seed projects +- Shared form components and auth screens +- Theme switching with Lager, Stout, Cassis, and Weizen variants +- Storybook documentation and automated story interaction tests +- Toast feedback for auth-related outcomes -### Planned +Planned next: -- [ ] Brewery discovery and management -- [ ] Beer reviews and ratings -- [ ] Social following/followers -- [ ] Geospatial brewery search -- [ ] Image upload (Cloudinary) -- [ ] Email notifications -- [ ] OAuth integration - ---- - -## Architecture Highlights - -### Layered Architecture - -``` -API Layer (Controllers) - │ -Service Layer (Business Logic) - │ -Infrastructure Layer (Repositories, JWT, Email) - │ -Domain Layer (Entities) - │ -Database (SQL Server + Stored Procedures) -``` - -### SQL-First Approach - -- All queries via stored procedures -- No ORM (no Entity Framework) -- Version-controlled schema - -### Security - -- **Password Hashing**: Argon2id (64MB memory, 4 iterations) -- **JWT Tokens**: HS256 with configurable expiration -- **Credential Rotation**: Built-in password change support - -See [Architecture Guide](docs/architecture.md) for details. - ---- +- Brewery discovery and management +- Beer reviews and ratings +- Social follow relationships +- Geospatial brewery experiences +- Additional frontend routes beyond the auth demo ## Testing -The project includes three test suites: +Backend suites: -| Suite | Type | Framework | Purpose | -| ---------------------- | ----------- | -------------- | ---------------------- | -| **API.Specs** | Integration | Reqnroll (BDD) | End-to-end API testing | -| **Repository.Tests** | Unit | xUnit | Data access layer | -| **Service.Auth.Tests** | Unit | xUnit + Moq | Business logic | +- `API.Specs` - integration tests +- `Infrastructure.Repository.Tests` - repository unit tests +- `Service.Auth.Tests` - service unit tests -**Run All Tests**: +Frontend suites: + +- Storybook interaction tests via Vitest +- Storybook browser regression checks via Playwright + +Run all backend tests with Docker: ```bash docker compose -f docker-compose.test.yaml up --abort-on-container-exit ``` -**Run Individual Test Suite**: - -```bash -cd src/Core -dotnet test API/API.Specs/API.Specs.csproj -dotnet test Infrastructure/Infrastructure.Repository.Tests/Infrastructure.Repository.Tests.csproj -dotnet test Service/Service.Auth.Tests/Service.Auth.Tests.csproj -``` - -See [Testing Guide](docs/testing.md) for more information. - ---- - -## Docker Environments - -The project uses three Docker Compose configurations: - -| File | Purpose | Features | -| ---------------------------- | ------------- | ------------------------------------------------- | -| **docker-compose.dev.yaml** | Development | Persistent data, hot reload, Swagger UI | -| **docker-compose.test.yaml** | CI/CD Testing | Isolated DB, auto-exit, test results export | -| **docker-compose.prod.yaml** | Production | Optimized builds, health checks, restart policies | - -**Common Commands**: - -```bash -# Development -docker compose -f docker-compose.dev.yaml up -d -docker compose -f docker-compose.dev.yaml logs -f api.core -docker compose -f docker-compose.dev.yaml down -v - -# Testing -docker compose -f docker-compose.test.yaml up --abort-on-container-exit -docker compose -f docker-compose.test.yaml down -v - -# Build -docker compose -f docker-compose.dev.yaml build -docker compose -f docker-compose.dev.yaml build --no-cache -``` - -See [Docker Guide](docs/docker.md) for troubleshooting and advanced usage. - ---- +See [Testing](docs/testing.md) for the full command list. ## Configuration -### Required Environment Variables +Common active variables: -**Backend** (`.env.dev`): +- Backend: `DB_SERVER`, `DB_NAME`, `DB_USER`, `DB_PASSWORD`, `ACCESS_TOKEN_SECRET`, `REFRESH_TOKEN_SECRET`, `CONFIRMATION_TOKEN_SECRET` +- Frontend: `API_BASE_URL`, `SESSION_SECRET`, `NODE_ENV` -```bash -DB_SERVER=sqlserver,1433 -DB_NAME=Biergarten -DB_USER=sa -DB_PASSWORD=YourStrong!Passw0rd -JWT_SECRET= -``` - -**Frontend** (`.env.local`): - -```bash -BASE_URL=http://localhost:3000 -NODE_ENV=development -CONFIRMATION_TOKEN_SECRET= -RESET_PASSWORD_TOKEN_SECRET= -SESSION_SECRET= -# + External services (Cloudinary, Mapbox, SparkPost) -``` - -See [Environment Variables Guide](docs/environment-variables.md) for complete reference. - ---- +See [Environment Variables](docs/environment-variables.md) for details. ## Contributing diff --git a/docs/architecture.md b/docs/architecture.md index b603191..758b0bf 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -1,28 +1,27 @@ # Architecture -This document describes the architecture patterns and design decisions for The Biergarten -App. +This document describes the active architecture of The Biergarten App. ## High-Level Overview -The Biergarten App follows a **multi-project monorepo** architecture with clear separation -between backend and frontend: +The Biergarten App is a monorepo with a clear split between the backend and the active +website: -- **Backend**: .NET 10 Web API with SQL Server -- **Frontend**: Next.js with TypeScript -- **Architecture Style**: Layered architecture with SQL-first approach +- **Backend**: .NET 10 Web API with SQL Server and a layered architecture +- **Frontend**: React 19 + React Router 7 website in `src/Website` +- **Architecture Style**: Layered backend plus server-rendered React frontend + +The legacy Next.js frontend has been retained in `src/Website-v1` for reference only and is +documented in [archive/legacy-website-v1.md](archive/legacy-website-v1.md). ## Diagrams For visual representations, see: -- [architecture.pdf](diagrams/pdf/architecture.pdf) - Layered architecture diagram -- [deployment.pdf](diagrams/pdf/deployment.pdf) - Docker deployment diagram -- [authentication-flow.pdf](diagrams/pdf/authentication-flow.pdf) - Authentication - workflow -- [database-schema.pdf](diagrams/pdf/database-schema.pdf) - Database relationships - -Generate diagrams with: `make diagrams` +- [architecture.svg](diagrams-out/architecture.svg) - Layered architecture diagram +- [deployment.svg](diagrams-out/deployment.svg) - Docker deployment diagram +- [authentication-flow.svg](diagrams-out/authentication-flow.svg) - Authentication workflow +- [database-schema.svg](diagrams-out/database-schema.svg) - Database relationships ## Backend Architecture @@ -217,39 +216,49 @@ public interface IAuthRepository ## Frontend Architecture -### Next.js Application Structure +### Active Website (`src/Website`) -``` -Website/src/ -├── components/ # React components -├── pages/ # Next.js routes -├── contexts/ # React context providers -├── hooks/ # Custom React hooks -├── controllers/ # Business logic layer -├── services/ # API communication -├── requests/ # API request builders -├── validation/ # Form validation schemas -├── config/ # Configuration & env vars -└── prisma/ # Database schema (current) +The current website is a React Router 7 application with server-side rendering enabled. + +```text +src/Website/ +├── app/ +│ ├── components/ Shared UI such as Navbar, FormField, SubmitButton, ToastProvider +│ ├── lib/ Auth helpers, schemas, and theme metadata +│ ├── routes/ Route modules for home, login, register, dashboard, confirm, theme +│ ├── root.tsx App shell and global providers +│ └── app.css Theme tokens and global styling +├── .storybook/ Storybook config and preview setup +├── stories/ Storybook stories for shared UI and themes +├── tests/playwright/ Storybook Playwright coverage +└── package.json Frontend scripts and dependencies ``` -### Migration Strategy +### Frontend Responsibilities -The frontend is **transitioning** from a standalone architecture to integrate with the -.NET API: +- Render the auth demo and theme guide routes +- Manage cookie-backed website session state +- Call the .NET API for login, registration, token refresh, and confirmation +- Provide shared UI building blocks for forms, navigation, themes, and toasts +- Supply Storybook documentation and browser-based component verification -**Current State**: +### Theme System -- Uses Prisma ORM with Postgres (Neon) -- Has its own server-side API routes -- Direct database access from Next.js +The active website uses semantic DaisyUI theme tokens backed by four Biergarten themes: -**Target State**: +- Biergarten Lager +- Biergarten Stout +- Biergarten Cassis +- Biergarten Weizen -- Pure client-side Next.js app -- All data via .NET API -- No server-side database access -- JWT-based authentication +All component styling should prefer semantic tokens such as `primary`, `success`, +`surface`, and `highlight` instead of hard-coded color values. + +### Legacy Frontend + +The previous Next.js frontend has been archived at `src/Website-v1`. Active product and +engineering documentation should point to `src/Website`, while legacy notes live in +[archive/legacy-website-v1.md](archive/legacy-website-v1.md). ## Security Architecture @@ -385,7 +394,7 @@ dependencies ```yaml healthcheck: - test: ['CMD-SHELL', 'sqlcmd health check'] + test: ["CMD-SHELL", "sqlcmd health check"] interval: 10s retries: 12 start_period: 30s diff --git a/docs/archive/legacy-website-v1.md b/docs/archive/legacy-website-v1.md new file mode 100644 index 0000000..f0a4db9 --- /dev/null +++ b/docs/archive/legacy-website-v1.md @@ -0,0 +1,56 @@ +# Legacy Website Archive (`src/Website-v1`) + +This archive captures high-level notes about the previous Biergarten frontend so active +project documentation can focus on the current website in `src/Website`. + +## Status + +- `src/Website-v1` is retained for historical reference only +- It is not the active frontend used by current setup, docs, or testing guidance +- New product and engineering work should target `src/Website` + +## Legacy Stack Summary + +The archived frontend used a different application model from the current website: + +- Next.js 14 +- React 18 +- Prisma +- Postgres / Neon-hosted database workflows +- Next.js API routes and server-side controllers +- Additional third-party integrations such as Cloudinary, Mapbox, and SparkPost + +## Why It Was Archived + +The active website moved to a React Router-based frontend that talks directly to the .NET +API. As part of that shift, the main docs were updated to describe: + +- `src/Website` as the active frontend +- React Router route modules and server rendering +- Storybook-based component documentation and tests +- Current frontend runtime variables: `API_BASE_URL`, `SESSION_SECRET`, and `NODE_ENV` + +## Legacy Documentation Topics Moved Out of Active Docs + +The following categories were removed from active documentation and intentionally archived: + +- Next.js application structure guidance +- Prisma and Postgres frontend setup +- Legacy frontend environment variables +- External service setup that only applied to `src/Website-v1` +- Old frontend local setup instructions + +## When To Use This Archive + +Use this file only if you need to: + +- inspect the historical frontend implementation +- compare old flows against the current website +- migrate or recover legacy logic from `src/Website-v1` + +For all active work, use: + +- [Getting Started](../getting-started.md) +- [Architecture](../architecture.md) +- [Environment Variables](../environment-variables.md) +- [Testing](../testing.md) diff --git a/docs/backlog/website-epic-post-9238036.md b/docs/backlog/website-epic-post-9238036.md new file mode 100644 index 0000000..370d116 --- /dev/null +++ b/docs/backlog/website-epic-post-9238036.md @@ -0,0 +1,205 @@ +# Epic: Modernize the Biergarten Website Experience + +Scope: Work representing the changes delivered after commit `9238036042006c3bc92045f785d53c71a8b8421d`. + +## Epic User Story + +**As a** Biergarten visitor, registered user, and frontend developer +**I want** a modern website experience with account flows, themed UI, reusable components, Storybook coverage, and reliable frontend tooling +**So that** the product is easier to use, easier to extend, and safer to ship + +## Epic Outcomes + +- Establish the current `src/Website` application as the active frontend workspace +- Deliver a working authentication demo flow with home, login, register, dashboard, logout, and confirmation states +- Expand the Biergarten visual system with multiple branded themes and a theme guide +- Document key UI components in Storybook with automated browser checks +- Add theme-aware toast feedback for auth and status messaging +- Improve formatting and ignore rules so developer tooling targets source files cleanly + +--- + +# Ticket 1: Establish the active website workspace + +## User Story + +**As a** frontend developer +**I want** the active website app to live in a clearly named `src/Website` workspace with the right config and assets +**So that** I can work in one canonical frontend without confusion + +## Acceptance Criteria (BDD) + +### Scenario 1: Active frontend workspace exists + +Given the repository contains multiple frontend codebases +When I inspect the active application workspace +Then the current website app is available under `src/Website` +And the project contains its runtime config, public assets, and package scripts + +### Scenario 2: Frontend scripts support local development + +Given I am onboarding to the website app +When I open the workspace package manifest +Then I can find commands for development, build, start, lint, format, typecheck, and Storybook + +### Scenario 3: Supporting config files are aligned + +Given the website workspace is the active frontend +When I review project configuration +Then the app includes React Router, Vite, Tailwind, PostCSS, ESLint, and Prettier configuration needed to run the app consistently + +## Subtasks + +- [ ] Move or rename the active frontend into `src/Website` +- [ ] Align package scripts and config files with the active workspace +- [ ] Confirm assets and public metadata move with the app + +--- + +# Ticket 2: Deliver the authentication demo flow + +## User Story + +**As a** visitor or returning user +**I want** to register, log in, confirm account state, and access a dashboard +**So that** I can validate the account journey end to end + +## Acceptance Criteria (BDD) + +### Scenario 1: Guests can reach auth entry points + +Given I am not authenticated +When I visit the home page +Then I can navigate to login and registration +And the page clearly presents the website as an authentication demo + +### Scenario 2: Guests can submit login and registration forms + +Given I am on the login or register page +When I enter valid information and submit +Then the app validates the request +And it creates an authenticated session on success +And it shows clear validation or failure feedback on error + +### Scenario 3: Authenticated users are redirected appropriately + +Given I already have an authenticated session +When I visit guest-only auth pages +Then I am redirected away from those pages +And I can access dashboard and logout flows from the authenticated experience + +## Subtasks + +- [ ] Add routes for home, login, register, logout, dashboard, and confirm +- [ ] Implement schema validation and auth session handling +- [ ] Build shared form components for the auth flow + +--- + +# Ticket 3: Introduce the Biergarten theme system + +## User Story + +**As a** Biergarten user +**I want** to switch between distinct Biergarten themes without losing usability +**So that** I can choose a visual mood while the interface stays consistent and readable + +## Acceptance Criteria (BDD) + +### Scenario 1: Multiple Biergarten themes are available + +Given I open the website +When I use the theme system +Then I can choose among Biergarten Lager, Biergarten Stout, Biergarten Cassis, and Biergarten Weizen + +### Scenario 2: Theme choice persists + +Given I select a theme +When I navigate or refresh the browser +Then the chosen theme remains active +And the app uses the stored preference when possible + +### Scenario 3: Theme guide demonstrates token usage + +Given I visit the theme guide page +When I inspect the examples +Then I can review brand colors, status colors, and component previews +And semantic token pairings remain readable in every theme + +## Subtasks + +- [ ] Define shared theme metadata and storage behavior +- [ ] Add or refine DaisyUI theme tokens in the website stylesheet +- [ ] Create a theme guide route with a live switcher and previews + +--- + +# Ticket 4: Add Storybook coverage for shared UI and themes + +## User Story + +**As a** frontend developer and designer +**I want** component and theme stories with automated checks +**So that** I can review shared UI in isolation and catch regressions before release + +## Acceptance Criteria (BDD) + +### Scenario 1: Shared components have story coverage + +Given I open Storybook +When I browse the component library +Then I can review stories for the shared submit button, form field, navbar, toast feedback, and theme gallery + +### Scenario 2: Storybook matches the app environment + +Given I preview a story +When I inspect typography, routing context, and themes +Then the stories use the website fonts, router-safe rendering, and theme switching consistent with the app + +### Scenario 3: Story interactions are testable + +Given Storybook stories include interaction coverage +When the Storybook test suite runs +Then the key stories verify their expected states and interactions successfully + +## Subtasks + +- [ ] Configure Storybook for the website workspace +- [ ] Add stories and docs for shared components and theme previews +- [ ] Add browser-based Storybook tests for story interactions + +--- + +# Ticket 5: Add toast-based user feedback + +## User Story + +**As a** website user +**I want** lightweight toast notifications for important auth outcomes +**So that** I receive immediate feedback without losing page context + +## Acceptance Criteria (BDD) + +### Scenario 1: Toast provider is available globally + +Given I navigate through the website +When a feature triggers a toast notification +Then a consistent toast container is already mounted in the app shell + +### Scenario 2: Auth flows show helpful status feedback + +Given I submit login, registration, or confirmation flows +When the app receives a success or error outcome +Then it shows a toast with the correct semantic styling and message + +### Scenario 3: Toast visuals adapt to the active theme + +Given I switch between Biergarten themes +When toast notifications appear +Then their surface, icon, and text colors remain legible and on-brand + +## Subtasks + +- [ ] Add a global toast provider and helper utilities +- [ ] Trigger toasts from auth-related routes +- [ ] Document the toast behavior in Storybook diff --git a/docs/environment-variables.md b/docs/environment-variables.md index d664a39..b7c262f 100644 --- a/docs/environment-variables.md +++ b/docs/environment-variables.md @@ -1,14 +1,15 @@ # Environment Variables -Complete documentation for all environment variables used in The Biergarten App. +This document covers the active environment variables used by the current Biergarten +stack. ## Overview -The application uses environment variables for configuration across: +The application uses environment variables for: -- **.NET API Backend** - Database connections, JWT secrets -- **Next.js Frontend** - External services, authentication -- **Docker Containers** - Runtime configuration +- **.NET API backend** - database connections, token secrets, runtime settings +- **React Router website** - API base URL and session signing +- **Docker containers** - environment-specific orchestration ## Configuration Patterns @@ -16,10 +17,10 @@ The application uses environment variables for configuration across: Direct environment variable access via `Environment.GetEnvironmentVariable()`. -### Frontend (Next.js) +### Frontend (`src/Website`) -Centralized configuration module at `src/Website/src/config/env/index.ts` with Zod -validation. +The active website reads runtime values from the server environment for its auth and API +integration. ### Docker @@ -128,91 +129,38 @@ ASPNETCORE_URLS=http://0.0.0.0:8080 # Binding address and port DOTNET_RUNNING_IN_CONTAINER=true # Flag for container execution ``` -## Frontend Variables (Next.js) +## Frontend Variables (`src/Website`) -Create `.env.local` in the `Website/` directory. - -### Base Configuration +The active website does not use the old Next.js/Prisma environment model. Its core runtime +variables are: ```bash -BASE_URL=http://localhost:3000 # Application base URL -NODE_ENV=development # Environment: development, production, test +API_BASE_URL=http://localhost:8080 # Base URL for the .NET API +SESSION_SECRET= # Cookie session signing secret +NODE_ENV=development # Standard Node runtime mode ``` -### Authentication & Sessions +### Frontend Variable Details -```bash -# Token signing secrets (use openssl rand -base64 127) -CONFIRMATION_TOKEN_SECRET= # Email confirmation tokens -RESET_PASSWORD_TOKEN_SECRET= # Password reset tokens -SESSION_SECRET= # Session cookie signing +#### `API_BASE_URL` -# Session configuration -SESSION_TOKEN_NAME=biergarten # Cookie name (optional) -SESSION_MAX_AGE=604800 # Cookie max age in seconds (optional, default: 1 week) -``` +- **Required**: Yes for local development +- **Default in code**: `http://localhost:8080` +- **Used by**: `src/Website/app/lib/auth.server.ts` +- **Purpose**: Routes website auth actions to the .NET API -**Security Requirements**: +#### `SESSION_SECRET` -- All secrets should be 127+ characters -- Generate using cryptographically secure random functions -- Never reuse secrets across environments -- Rotate secrets periodically in production +- **Required**: Strongly recommended in all environments +- **Default in local code path**: `dev-secret-change-me` +- **Used by**: React Router cookie session storage in `auth.server.ts` +- **Purpose**: Signs and validates the website session cookie -### Database (Current - Prisma/Postgres) +#### `NODE_ENV` -**Note**: Frontend currently uses Neon Postgres. Will migrate to .NET API. - -```bash -POSTGRES_PRISMA_URL=postgresql://user:pass@host/db?pgbouncer=true # Pooled connection -POSTGRES_URL_NON_POOLING=postgresql://user:pass@host/db # Direct connection (migrations) -SHADOW_DATABASE_URL=postgresql://user:pass@host/shadow_db # Prisma shadow DB (optional) -``` - -### External Services - -#### Cloudinary (Image Hosting) - -```bash -NEXT_PUBLIC_CLOUDINARY_CLOUD_NAME=your-cloud-name # Public, client-accessible -CLOUDINARY_KEY=your-api-key # Server-side API key -CLOUDINARY_SECRET=your-api-secret # Server-side secret -``` - -**Setup Steps**: - -1. Sign up at [cloudinary.com](https://cloudinary.com) -2. Navigate to Dashboard -3. Copy Cloud Name, API Key, and API Secret - -**Note**: `NEXT_PUBLIC_` prefix makes variable accessible in client-side code. - -#### Mapbox (Maps & Geocoding) - -```bash -MAPBOX_ACCESS_TOKEN=pk.your-public-token -``` - -**Setup Steps**: - -1. Create account at [mapbox.com](https://mapbox.com) -2. Navigate to Account → Tokens -3. Create new token with public scopes -4. Copy access token - -#### SparkPost (Email Service) - -```bash -SPARKPOST_API_KEY=your-api-key -SPARKPOST_SENDER_ADDRESS=noreply@yourdomain.com -``` - -**Setup Steps**: - -1. Sign up at [sparkpost.com](https://sparkpost.com) -2. Verify sending domain or use sandbox -3. Create API key with "Send via SMTP" permission -4. Configure sender address (must match verified domain) +- **Required**: No +- **Typical values**: `development`, `production`, `test` +- **Purpose**: Controls secure cookie behavior and runtime mode ### Admin Account (Seeding) @@ -258,72 +206,42 @@ cp .env.example .env.dev # Edit .env.dev with your values ``` +## Legacy Frontend Variables + +Variables for the archived Next.js frontend (`src/Website-v1`) have been removed from this +active reference. See [archive/legacy-website-v1.md](archive/legacy-website-v1.md) if you +need the legacy Prisma, Cloudinary, Mapbox, or SparkPost notes. + **Docker Compose Mapping**: - `docker-compose.dev.yaml` → `.env.dev` - `docker-compose.test.yaml` → `.env.test` - `docker-compose.prod.yaml` → `.env.prod` -### Frontend (Website Directory) - -``` -.env.local # Local development (gitignored) -.env.production # Production (gitignored) -``` - -**Setup**: - -```bash -cd Website -touch .env.local -# Add frontend variables -``` - ## Variable Reference Table -| Variable | Backend | Frontend | Docker | Required | Notes | -| ----------------------------------- | :-----: | :------: | :----: | :------: | ------------------------- | -| **Database** | -| `DB_SERVER` | ✓ | | ✓ | Yes\* | SQL Server address | -| `DB_NAME` | ✓ | | ✓ | Yes\* | Database name | -| `DB_USER` | ✓ | | ✓ | Yes\* | SQL username | -| `DB_PASSWORD` | ✓ | | ✓ | Yes\* | SQL password | -| `DB_CONNECTION_STRING` | ✓ | | | Yes\* | Alternative to components | -| `DB_TRUST_SERVER_CERTIFICATE` | ✓ | | ✓ | No | Defaults to True | -| `SA_PASSWORD` | | | ✓ | Yes | SQL Server container | -| **Authentication (Backend - JWT)** | -| `ACCESS_TOKEN_SECRET` | ✓ | | ✓ | Yes | Access token secret | -| `REFRESH_TOKEN_SECRET` | ✓ | | ✓ | Yes | Refresh token secret | -| `CONFIRMATION_TOKEN_SECRET` | ✓ | | ✓ | Yes | Confirmation token secret | -| `WEBSITE_BASE_URL` | ✓ | | | Yes | Website URL for emails | -| **Authentication (Frontend)** | -| `CONFIRMATION_TOKEN_SECRET` | | ✓ | | Yes | Email confirmation | -| `RESET_PASSWORD_TOKEN_SECRET` | | ✓ | | Yes | Password reset | -| `SESSION_SECRET` | | ✓ | | Yes | Session signing | -| `SESSION_TOKEN_NAME` | | ✓ | | No | Default: "biergarten" | -| `SESSION_MAX_AGE` | | ✓ | | No | Default: 604800 | -| **Base Configuration** | -| `BASE_URL` | | ✓ | | Yes | App base URL | -| `NODE_ENV` | | ✓ | | Yes | Node environment | -| `ASPNETCORE_ENVIRONMENT` | ✓ | | ✓ | Yes | ASP.NET environment | -| `ASPNETCORE_URLS` | ✓ | | ✓ | Yes | API binding address | -| **Database (Frontend - Current)** | -| `POSTGRES_PRISMA_URL` | | ✓ | | Yes | Pooled connection | -| `POSTGRES_URL_NON_POOLING` | | ✓ | | Yes | Direct connection | -| `SHADOW_DATABASE_URL` | | ✓ | | No | Prisma shadow DB | -| **External Services** | -| `NEXT_PUBLIC_CLOUDINARY_CLOUD_NAME` | | ✓ | | Yes | Public, client-side | -| `CLOUDINARY_KEY` | | ✓ | | Yes | Server-side | -| `CLOUDINARY_SECRET` | | ✓ | | Yes | Server-side | -| `MAPBOX_ACCESS_TOKEN` | | ✓ | | Yes | Maps/geocoding | -| `SPARKPOST_API_KEY` | | ✓ | | Yes | Email service | -| `SPARKPOST_SENDER_ADDRESS` | | ✓ | | Yes | From address | -| **Other** | -| `ADMIN_PASSWORD` | | ✓ | | No | Seeding only | -| `CLEAR_DATABASE` | ✓ | | ✓ | No | Dev/test only | -| `ACCEPT_EULA` | | | ✓ | Yes | SQL Server EULA | -| `MSSQL_PID` | | | ✓ | No | SQL Server edition | -| `DOTNET_RUNNING_IN_CONTAINER` | ✓ | | ✓ | No | Container flag | +| Variable | Backend | Frontend | Docker | Required | Notes | +| ----------------------------- | :-----: | :------: | :----: | :------: | -------------------------- | +| `DB_SERVER` | ✓ | | ✓ | Yes\* | SQL Server address | +| `DB_NAME` | ✓ | | ✓ | Yes\* | Database name | +| `DB_USER` | ✓ | | ✓ | Yes\* | SQL username | +| `DB_PASSWORD` | ✓ | | ✓ | Yes\* | SQL password | +| `DB_CONNECTION_STRING` | ✓ | | | Yes\* | Alternative to components | +| `DB_TRUST_SERVER_CERTIFICATE` | ✓ | | ✓ | No | Defaults to `True` | +| `ACCESS_TOKEN_SECRET` | ✓ | | ✓ | Yes | Access token signing | +| `REFRESH_TOKEN_SECRET` | ✓ | | ✓ | Yes | Refresh token signing | +| `CONFIRMATION_TOKEN_SECRET` | ✓ | | ✓ | Yes | Confirmation token signing | +| `WEBSITE_BASE_URL` | ✓ | | | Yes | Website URL for emails | +| `API_BASE_URL` | | ✓ | | Yes | Website-to-API base URL | +| `SESSION_SECRET` | | ✓ | | Yes | Website session signing | +| `NODE_ENV` | | ✓ | | No | Runtime mode | +| `CLEAR_DATABASE` | ✓ | | ✓ | No | Dev/test reset flag | +| `ASPNETCORE_ENVIRONMENT` | ✓ | | ✓ | Yes | ASP.NET environment | +| `ASPNETCORE_URLS` | ✓ | | ✓ | Yes | API binding address | +| `SA_PASSWORD` | | | ✓ | Yes | SQL Server container | +| `ACCEPT_EULA` | | | ✓ | Yes | SQL Server EULA | +| `MSSQL_PID` | | | ✓ | No | SQL Server edition | +| `DOTNET_RUNNING_IN_CONTAINER` | ✓ | | ✓ | No | Container flag | \* Either `DB_CONNECTION_STRING` OR the component variables (`DB_SERVER`, `DB_NAME`, `DB_USER`, `DB_PASSWORD`) must be provided. @@ -340,13 +258,12 @@ Variables are validated at startup: ### Frontend Validation -Zod schemas validate variables at runtime: +The active website relies on runtime defaults for local development and the surrounding +server environment in deployed environments. -- Type checking (string, number, URL, etc.) -- Format validation (email, URL patterns) -- Required vs optional enforcement - -**Location**: `src/Website/src/config/env/index.ts` +- `API_BASE_URL` defaults to `http://localhost:8080` +- `SESSION_SECRET` falls back to a development-only local secret +- `NODE_ENV` controls secure cookie behavior ## Example Configuration Files @@ -378,28 +295,10 @@ ACCEPT_EULA=Y MSSQL_PID=Express ``` -### `.env.local` (Frontend) +### Frontend local runtime example ```bash -# Base -BASE_URL=http://localhost:3000 -NODE_ENV=development - -# Authentication +API_BASE_URL=http://localhost:8080 SESSION_SECRET= - -# Database (current Prisma setup) -POSTGRES_PRISMA_URL=postgresql://user:pass@db.neon.tech/biergarten?pgbouncer=true -POSTGRES_URL_NON_POOLING=postgresql://user:pass@db.neon.tech/biergarten - -# External Services -NEXT_PUBLIC_CLOUDINARY_CLOUD_NAME=my-cloud -CLOUDINARY_KEY=123456789012345 -CLOUDINARY_SECRET=abcdefghijklmnopqrstuvwxyz -MAPBOX_ACCESS_TOKEN=pk.eyJ... -SPARKPOST_API_KEY=abc123... -SPARKPOST_SENDER_ADDRESS=noreply@biergarten.app - -# Admin (for seeding) -ADMIN_PASSWORD=Admin_Dev_Password_123! +NODE_ENV=development ``` diff --git a/docs/getting-started.md b/docs/getting-started.md index 8074b94..91b0672 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -1,19 +1,16 @@ # Getting Started -This guide will help you set up and run The Biergarten App in your development -environment. +This guide covers local setup for the current Biergarten stack: the .NET backend in +`src/Core` and the active React Router frontend in `src/Website`. ## Prerequisites -Before you begin, ensure you have the following installed: +- **.NET SDK 10+** +- **Node.js 18+** +- **Docker Desktop** or equivalent Docker Engine setup +- **Java 8+** if you want to regenerate PlantUML diagrams -- **.NET SDK 10+** - [Download](https://dotnet.microsoft.com/download) -- **Node.js 18+** - [Download](https://nodejs.org/) -- **Docker Desktop** - [Download](https://www.docker.com/products/docker-desktop) - (recommended) -- **Java 8+** - Required for generating diagrams from PlantUML (optional) - -## Quick Start with Docker (Recommended) +## Recommended Path: Docker for Backend, Node for Frontend ### 1. Clone the Repository @@ -22,174 +19,120 @@ git clone cd the-biergarten-app ``` -### 2. Configure Environment Variables - -Copy the example environment file: +### 2. Configure Backend Environment Variables ```bash cp .env.example .env.dev ``` -Edit `.env.dev` with your configuration: +At minimum, ensure `.env.dev` includes valid database and token values: ```bash -# Database (component-based for Docker) DB_SERVER=sqlserver,1433 DB_NAME=Biergarten DB_USER=sa DB_PASSWORD=YourStrong!Passw0rd - -# JWT Authentication -JWT_SECRET=your-secret-key-minimum-32-characters-required +ACCESS_TOKEN_SECRET= +REFRESH_TOKEN_SECRET= +CONFIRMATION_TOKEN_SECRET= +WEBSITE_BASE_URL=http://localhost:3000 ``` -> For a complete list of environment variables, see -> [Environment Variables](environment-variables.md). +See [Environment Variables](environment-variables.md) for the full list. -### 3. Start the Development Environment +### 3. Start the Backend Stack ```bash docker compose -f docker-compose.dev.yaml up -d ``` -This command will: +This starts SQL Server, migrations, seeding, and the API. -- Start SQL Server container -- Run database migrations -- Seed initial data -- Start the API on http://localhost:8080 +Available endpoints: -### 4. Access the API +- API Swagger: http://localhost:8080/swagger +- Health Check: http://localhost:8080/health -- **Swagger UI**: http://localhost:8080/swagger -- **Health Check**: http://localhost:8080/health - -### 5. View Logs +### 4. Start the Active Frontend ```bash -# All services -docker compose -f docker-compose.dev.yaml logs -f - -# Specific service -docker compose -f docker-compose.dev.yaml logs -f api.core +cd src/Website +npm install +API_BASE_URL=http://localhost:8080 SESSION_SECRET=dev-secret-change-me npm run dev ``` -### 6. Stop the Environment +The website will be available at the local address printed by React Router dev. + +Required frontend runtime variables for local work: + +- `API_BASE_URL` - Base URL for the .NET API +- `SESSION_SECRET` - Cookie session signing secret for the website server + +### 5. Optional: Run Storybook ```bash -docker compose -f docker-compose.dev.yaml down +cd src/Website +npm run storybook +``` -# Remove volumes (fresh start) +Storybook runs at http://localhost:6006 by default. + +## Useful Commands + +### Backend + +```bash +docker compose -f docker-compose.dev.yaml logs -f +docker compose -f docker-compose.dev.yaml down docker compose -f docker-compose.dev.yaml down -v ``` -## Manual Setup (Without Docker) - -If you prefer to run services locally without Docker: - -### Backend Setup - -#### 1. Start SQL Server - -You can use a local SQL Server instance or a cloud-hosted one. Ensure it's accessible and -you have the connection details. - -#### 2. Set Environment Variables +### Frontend ```bash -# macOS/Linux -export DB_CONNECTION_STRING="Server=localhost,1433;Database=Biergarten;User Id=sa;Password=YourStrong!Passw0rd;TrustServerCertificate=True;" -export JWT_SECRET="your-secret-key-minimum-32-characters-required" - -# Windows PowerShell -$env:DB_CONNECTION_STRING="Server=localhost,1433;Database=Biergarten;User Id=sa;Password=YourStrong!Passw0rd;TrustServerCertificate=True;" -$env:JWT_SECRET="your-secret-key-minimum-32-characters-required" +cd src/Website +npm run lint +npm run typecheck +npm run format:check +npm run test:storybook +npm run test:storybook:playwright ``` -#### 3. Run Database Migrations +## Manual Backend Setup + +If you do not want to use Docker, you can run the backend locally. + +### 1. Set Environment Variables + +```bash +export DB_CONNECTION_STRING="Server=localhost,1433;Database=Biergarten;User Id=sa;Password=YourStrong!Passw0rd;TrustServerCertificate=True;" +export ACCESS_TOKEN_SECRET="" +export REFRESH_TOKEN_SECRET="" +export CONFIRMATION_TOKEN_SECRET="" +export WEBSITE_BASE_URL="http://localhost:3000" +``` + +### 2. Run Migrations and Seed ```bash cd src/Core dotnet run --project Database/Database.Migrations/Database.Migrations.csproj -``` - -#### 4. Seed the Database - -```bash dotnet run --project Database/Database.Seed/Database.Seed.csproj ``` -#### 5. Start the API +### 3. Start the API ```bash dotnet run --project API/API.Core/API.Core.csproj ``` -The API will be available at http://localhost:5000 (or the port specified in -launchSettings.json). - -### Frontend Setup - -> **Note**: The frontend is currently transitioning from its standalone Prisma/Postgres -> backend to the .NET API. Some features may still use the old backend. - -#### 1. Navigate to Website Directory - -```bash -cd Website -``` - -#### 2. Create Environment File - -Create `.env.local` with frontend variables. See -[Environment Variables - Frontend](environment-variables.md#frontend-variables) for the -complete list. - -```bash -BASE_URL=http://localhost:3000 -NODE_ENV=development - -# Generate secrets -CONFIRMATION_TOKEN_SECRET=$(openssl rand -base64 127) -RESET_PASSWORD_TOKEN_SECRET=$(openssl rand -base64 127) -SESSION_SECRET=$(openssl rand -base64 127) - -# External services (you'll need to register for these) -NEXT_PUBLIC_CLOUDINARY_CLOUD_NAME=your-cloud-name -CLOUDINARY_KEY=your-api-key -CLOUDINARY_SECRET=your-api-secret -NEXT_PUBLIC_MAPBOX_KEY=your-mapbox-token - -# Database URL (current Prisma setup) -DATABASE_URL=your-postgres-connection-string -``` - -#### 3. Install Dependencies - -```bash -npm install -``` - -#### 4. Run Prisma Migrations - -```bash -npx prisma generate -npx prisma migrate dev -``` - -#### 5. Start Development Server - -```bash -npm run dev -``` - -The frontend will be available at http://localhost:3000. +## Legacy Frontend Note +The previous Next.js frontend now lives in `src/Website-v1` and is not the active website. +Legacy setup details have been moved to [docs/archive/legacy-website-v1.md](archive/legacy-website-v1.md). ## Next Steps -- **Test the API**: Visit http://localhost:8080/swagger and try the endpoints -- **Run Tests**: See [Testing Guide](testing.md) -- **Learn the Architecture**: Read [Architecture Overview](architecture.md) -- **Understand Docker Setup**: See [Docker Guide](docker.md) -- **Database Details**: Check [Database Schema](database.md) +- Review [Architecture](architecture.md) +- Run backend and frontend checks from [Testing](testing.md) +- Use [Docker Guide](docker.md) for container troubleshooting diff --git a/docs/testing.md b/docs/testing.md index 81d95c5..098fab4 100644 --- a/docs/testing.md +++ b/docs/testing.md @@ -4,11 +4,13 @@ This document describes the testing strategy and how to run tests for The Bierga ## Overview -The project uses a multi-layered testing approach: +The project uses a multi-layered testing approach across backend and frontend: - **API.Specs** - BDD integration tests using Reqnroll (Gherkin) - **Infrastructure.Repository.Tests** - Unit tests for data access layer - **Service.Auth.Tests** - Unit tests for authentication business logic +- **Storybook Vitest project** - Browser-based interaction tests for shared website stories +- **Storybook Playwright suite** - Browser checks against Storybook-rendered components ## Running Tests with Docker (Recommended) @@ -86,6 +88,33 @@ dotnet test Service/Service.Auth.Tests/Service.Auth.Tests.csproj - No database required (uses Moq for mocking) +### Frontend Storybook Tests + +```bash +cd src/Website +npm install +npm run test:storybook +``` + +**Purpose**: + +- Verifies shared stories such as form fields, submit buttons, navbar states, toasts, and the theme gallery +- Runs in browser mode via Vitest and Storybook integration + +### Frontend Playwright Storybook Tests + +```bash +cd src/Website +npm install +npm run test:storybook:playwright +``` + +**Requirements**: + +- Storybook dependencies installed +- Playwright browser dependencies installed +- The command will start or reuse the Storybook server defined in `playwright.storybook.config.ts` + ## Test Coverage ### Current Coverage @@ -112,6 +141,14 @@ dotnet test Service/Service.Auth.Tests/Service.Auth.Tests.csproj - Register service with validation - Business logic for authentication flow +**Frontend UI Coverage**: + +- Shared submit button states +- Form field happy path and error presentation +- Navbar guest, authenticated, and mobile behavior +- Theme gallery rendering across Biergarten themes +- Toast interactions and themed notification display + ### Planned Coverage - [ ] Email verification workflow @@ -121,6 +158,7 @@ dotnet test Service/Service.Auth.Tests/Service.Auth.Tests.csproj - [ ] Beer post operations - [ ] User follow/unfollow - [ ] Image upload service +- [ ] Frontend route integration coverage beyond Storybook stories ## Testing Frameworks & Tools @@ -254,6 +292,15 @@ Exit codes: - `0` - All tests passed - Non-zero - Test failures occurred +Frontend UI checks should also be included in CI for the active website workspace: + +```bash +cd src/Website +npm ci +npm run test:storybook +npm run test:storybook:playwright +``` + ## Troubleshooting ### Tests Failing Due to Database Connection