Update docs

This commit is contained in:
Aaron Po
2026-03-15 22:31:04 -04:00
parent a580fc6cbd
commit f4757979cc
7 changed files with 579 additions and 539 deletions

285
README.md
View File

@@ -1,261 +1,142 @@
# The Biergarten App # The Biergarten App
A social platform for craft beer enthusiasts to discover breweries, share reviews, and The Biergarten App is a multi-project monorepo with a .NET backend and an active React
connect with fellow beer lovers. 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 - [Getting Started](docs/getting-started.md) - Local setup for backend and active website
- [Architecture](docs/architecture.md) - System design and patterns - [Architecture](docs/architecture.md) - Current backend and frontend architecture
- [Database](docs/database.md) - Schema and stored procedures - [Docker Guide](docs/docker.md) - Container-based backend development and testing
- [Docker Guide](docs/docker.md) - Container deployment - [Testing](docs/testing.md) - Backend and frontend test commands
- [Testing](docs/testing.md) - Test strategy and commands - [Environment Variables](docs/environment-variables.md) - Active configuration reference
- [Environment Variables](docs/environment-variables.md) - 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 - [Architecture](docs/diagrams-out/architecture.svg) - Layered architecture
- [Deployment](docs/diagrams/pdf/deployment.pdf) - Docker topology - [Deployment](docs/diagrams-out/deployment.svg) - Docker topology
- [Authentication Flow](docs/diagrams/pdf/authentication-flow.pdf) - Auth sequence - [Authentication Flow](docs/diagrams-out/authentication-flow.svg) - Auth sequence
- [Database Schema](docs/diagrams/pdf/database-schema.pdf) - Entity relationships - [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 - .NET 10 backend with layered architecture and SQL Server
- Database schema with migrations and seeding - React Router 7 website in `src/Website`
- Layered architecture (Domain, Service, Infrastructure, Repository, API) - Shared Biergarten theme system with a theme guide route
- Comprehensive test suite (unit + integration) - Storybook stories and browser-based checks for shared UI
- Frontend integration with .NET API (in progress) - Auth demo flows for home, login, register, dashboard, logout, and confirmation
- Migration from Next.js serverless functions - 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 ## Tech Stack
**Backend**: .NET 10, ASP.NET Core, SQL Server 2022, DbUp **Frontend**: Next.js 14+, - **Backend**: .NET 10, ASP.NET Core, SQL Server 2022, DbUp
TypeScript, TailwindCSS **Testing**: xUnit, Reqnroll (BDD), FluentAssertions, Moq - **Frontend**: React 19, React Router 7, Vite 7, Tailwind CSS 4, DaisyUI 5
**Infrastructure**: Docker, Docker Compose **Security**: Argon2id password hashing, JWT - **UI Documentation**: Storybook 10, Vitest browser mode, Playwright
(HS256) - **Testing**: xUnit, Reqnroll (BDD), FluentAssertions, Moq
- **Infrastructure**: Docker, Docker Compose
--- - **Security**: Argon2id password hashing, JWT access/refresh/confirmation tokens
## Quick Start ## Quick Start
### Prerequisites ### Backend
- [.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
```bash ```bash
# Clone repository
git clone https://github.com/aaronpo97/the-biergarten-app git clone https://github.com/aaronpo97/the-biergarten-app
cd the-biergarten-app cd the-biergarten-app
# Configure environment
cp .env.example .env.dev cp .env.example .env.dev
# Start all services
docker compose -f docker-compose.dev.yaml up -d 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 - API Swagger: http://localhost:8080/swagger
- Health: http://localhost:8080/health - Health Check: http://localhost:8080/health
### Run Tests ### Frontend
```bash ```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 ## 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 ## Key Features
### Implemented Implemented today:
- User registration and authentication - User registration and login against the API
- JWT token-based auth - JWT-based auth with access, refresh, and confirmation flows
- Argon2id password hashing - SQL Server migrations and seed projects
- SQL Server with stored procedures - Shared form components and auth screens
- Database migrations (DbUp) - Theme switching with Lager, Stout, Cassis, and Weizen variants
- Docker containerization - Storybook documentation and automated story interaction tests
- Comprehensive test suite - Toast feedback for auth-related outcomes
- Swagger/OpenAPI documentation
- Health checks
### Planned Planned next:
- [ ] Brewery discovery and management - Brewery discovery and management
- [ ] Beer reviews and ratings - Beer reviews and ratings
- [ ] Social following/followers - Social follow relationships
- [ ] Geospatial brewery search - Geospatial brewery experiences
- [ ] Image upload (Cloudinary) - Additional frontend routes beyond the auth demo
- [ ] 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.
---
## Testing ## Testing
The project includes three test suites: Backend suites:
| Suite | Type | Framework | Purpose | - `API.Specs` - integration tests
| ---------------------- | ----------- | -------------- | ---------------------- | - `Infrastructure.Repository.Tests` - repository unit tests
| **API.Specs** | Integration | Reqnroll (BDD) | End-to-end API testing | - `Service.Auth.Tests` - service unit tests
| **Repository.Tests** | Unit | xUnit | Data access layer |
| **Service.Auth.Tests** | Unit | xUnit + Moq | Business logic |
**Run All Tests**: Frontend suites:
- Storybook interaction tests via Vitest
- Storybook browser regression checks via Playwright
Run all backend tests with Docker:
```bash ```bash
docker compose -f docker-compose.test.yaml up --abort-on-container-exit docker compose -f docker-compose.test.yaml up --abort-on-container-exit
``` ```
**Run Individual Test Suite**: See [Testing](docs/testing.md) for the full command list.
```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.
---
## Configuration ## 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 See [Environment Variables](docs/environment-variables.md) for details.
DB_SERVER=sqlserver,1433
DB_NAME=Biergarten
DB_USER=sa
DB_PASSWORD=YourStrong!Passw0rd
JWT_SECRET=<min-32-chars>
```
**Frontend** (`.env.local`):
```bash
BASE_URL=http://localhost:3000
NODE_ENV=development
CONFIRMATION_TOKEN_SECRET=<generated>
RESET_PASSWORD_TOKEN_SECRET=<generated>
SESSION_SECRET=<generated>
# + External services (Cloudinary, Mapbox, SparkPost)
```
See [Environment Variables Guide](docs/environment-variables.md) for complete reference.
---
## Contributing ## Contributing

View File

@@ -1,28 +1,27 @@
# Architecture # Architecture
This document describes the architecture patterns and design decisions for The Biergarten This document describes the active architecture of The Biergarten App.
App.
## High-Level Overview ## High-Level Overview
The Biergarten App follows a **multi-project monorepo** architecture with clear separation The Biergarten App is a monorepo with a clear split between the backend and the active
between backend and frontend: website:
- **Backend**: .NET 10 Web API with SQL Server - **Backend**: .NET 10 Web API with SQL Server and a layered architecture
- **Frontend**: Next.js with TypeScript - **Frontend**: React 19 + React Router 7 website in `src/Website`
- **Architecture Style**: Layered architecture with SQL-first approach - **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 ## Diagrams
For visual representations, see: For visual representations, see:
- [architecture.pdf](diagrams/pdf/architecture.pdf) - Layered architecture diagram - [architecture.svg](diagrams-out/architecture.svg) - Layered architecture diagram
- [deployment.pdf](diagrams/pdf/deployment.pdf) - Docker deployment diagram - [deployment.svg](diagrams-out/deployment.svg) - Docker deployment diagram
- [authentication-flow.pdf](diagrams/pdf/authentication-flow.pdf) - Authentication - [authentication-flow.svg](diagrams-out/authentication-flow.svg) - Authentication workflow
workflow - [database-schema.svg](diagrams-out/database-schema.svg) - Database relationships
- [database-schema.pdf](diagrams/pdf/database-schema.pdf) - Database relationships
Generate diagrams with: `make diagrams`
## Backend Architecture ## Backend Architecture
@@ -217,39 +216,49 @@ public interface IAuthRepository
## Frontend Architecture ## Frontend Architecture
### Next.js Application Structure ### Active Website (`src/Website`)
``` The current website is a React Router 7 application with server-side rendering enabled.
Website/src/
├── components/ # React components ```text
├── pages/ # Next.js routes src/Website/
├── contexts/ # React context providers ├── app/
├── hooks/ # Custom React hooks │ ├── components/ Shared UI such as Navbar, FormField, SubmitButton, ToastProvider
├── controllers/ # Business logic layer │ ├── lib/ Auth helpers, schemas, and theme metadata
├── services/ # API communication │ ├── routes/ Route modules for home, login, register, dashboard, confirm, theme
├── requests/ # API request builders ├── root.tsx App shell and global providers
├── validation/ # Form validation schemas │ └── app.css Theme tokens and global styling
├── config/ # Configuration & env vars ├── .storybook/ Storybook config and preview setup
── prisma/ # Database schema (current) ── 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 - Render the auth demo and theme guide routes
.NET API: - 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) The active website uses semantic DaisyUI theme tokens backed by four Biergarten themes:
- Has its own server-side API routes
- Direct database access from Next.js
**Target State**: - Biergarten Lager
- Biergarten Stout
- Biergarten Cassis
- Biergarten Weizen
- Pure client-side Next.js app All component styling should prefer semantic tokens such as `primary`, `success`,
- All data via .NET API `surface`, and `highlight` instead of hard-coded color values.
- No server-side database access
- JWT-based authentication ### 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 ## Security Architecture
@@ -385,7 +394,7 @@ dependencies
```yaml ```yaml
healthcheck: healthcheck:
test: ['CMD-SHELL', 'sqlcmd health check'] test: ["CMD-SHELL", "sqlcmd health check"]
interval: 10s interval: 10s
retries: 12 retries: 12
start_period: 30s start_period: 30s

View File

@@ -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)

View File

@@ -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

View File

@@ -1,14 +1,15 @@
# Environment Variables # 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 ## Overview
The application uses environment variables for configuration across: The application uses environment variables for:
- **.NET API Backend** - Database connections, JWT secrets - **.NET API backend** - database connections, token secrets, runtime settings
- **Next.js Frontend** - External services, authentication - **React Router website** - API base URL and session signing
- **Docker Containers** - Runtime configuration - **Docker containers** - environment-specific orchestration
## Configuration Patterns ## Configuration Patterns
@@ -16,10 +17,10 @@ The application uses environment variables for configuration across:
Direct environment variable access via `Environment.GetEnvironmentVariable()`. 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 The active website reads runtime values from the server environment for its auth and API
validation. integration.
### Docker ### 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 DOTNET_RUNNING_IN_CONTAINER=true # Flag for container execution
``` ```
## Frontend Variables (Next.js) ## Frontend Variables (`src/Website`)
Create `.env.local` in the `Website/` directory. The active website does not use the old Next.js/Prisma environment model. Its core runtime
variables are:
### Base Configuration
```bash ```bash
BASE_URL=http://localhost:3000 # Application base URL API_BASE_URL=http://localhost:8080 # Base URL for the .NET API
NODE_ENV=development # Environment: development, production, test SESSION_SECRET=<generated-secret> # Cookie session signing secret
NODE_ENV=development # Standard Node runtime mode
``` ```
### Authentication & Sessions ### Frontend Variable Details
```bash #### `API_BASE_URL`
# Token signing secrets (use openssl rand -base64 127)
CONFIRMATION_TOKEN_SECRET=<generated-secret> # Email confirmation tokens
RESET_PASSWORD_TOKEN_SECRET=<generated-secret> # Password reset tokens
SESSION_SECRET=<generated-secret> # Session cookie signing
# Session configuration - **Required**: Yes for local development
SESSION_TOKEN_NAME=biergarten # Cookie name (optional) - **Default in code**: `http://localhost:8080`
SESSION_MAX_AGE=604800 # Cookie max age in seconds (optional, default: 1 week) - **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 - **Required**: Strongly recommended in all environments
- Generate using cryptographically secure random functions - **Default in local code path**: `dev-secret-change-me`
- Never reuse secrets across environments - **Used by**: React Router cookie session storage in `auth.server.ts`
- Rotate secrets periodically in production - **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. - **Required**: No
- **Typical values**: `development`, `production`, `test`
```bash - **Purpose**: Controls secure cookie behavior and runtime mode
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)
### Admin Account (Seeding) ### Admin Account (Seeding)
@@ -258,72 +206,42 @@ cp .env.example .env.dev
# Edit .env.dev with your values # 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 Mapping**:
- `docker-compose.dev.yaml``.env.dev` - `docker-compose.dev.yaml``.env.dev`
- `docker-compose.test.yaml``.env.test` - `docker-compose.test.yaml``.env.test`
- `docker-compose.prod.yaml``.env.prod` - `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 Reference Table
| Variable | Backend | Frontend | Docker | Required | Notes | | Variable | Backend | Frontend | Docker | Required | Notes |
| ----------------------------------- | :-----: | :------: | :----: | :------: | ------------------------- | | ----------------------------- | :-----: | :------: | :----: | :------: | -------------------------- |
| **Database** | | `DB_SERVER` | ✓ | | ✓ | Yes\* | SQL Server address |
| `DB_SERVER` | ✓ | | ✓ | Yes\* | SQL Server address | | `DB_NAME` | ✓ | | ✓ | Yes\* | Database name |
| `DB_NAME` | ✓ | | ✓ | Yes\* | Database name | | `DB_USER` | ✓ | | ✓ | Yes\* | SQL username |
| `DB_USER` | ✓ | | ✓ | Yes\* | SQL username | | `DB_PASSWORD` | ✓ | | ✓ | Yes\* | SQL password |
| `DB_PASSWORD` | ✓ | | | Yes\* | SQL password | | `DB_CONNECTION_STRING` | ✓ | | | Yes\* | Alternative to components |
| `DB_CONNECTION_STRING` | ✓ | | | Yes\* | Alternative to components | | `DB_TRUST_SERVER_CERTIFICATE` | ✓ | | | No | Defaults to `True` |
| `DB_TRUST_SERVER_CERTIFICATE` | ✓ | | ✓ | No | Defaults to True | | `ACCESS_TOKEN_SECRET` | ✓ | | ✓ | Yes | Access token signing |
| `SA_PASSWORD` | | | ✓ | Yes | SQL Server container | | `REFRESH_TOKEN_SECRET` | | | ✓ | Yes | Refresh token signing |
| **Authentication (Backend - JWT)** | | `CONFIRMATION_TOKEN_SECRET` | ✓ | | ✓ | Yes | Confirmation token signing |
| `ACCESS_TOKEN_SECRET` | ✓ | | | Yes | Access token secret | | `WEBSITE_BASE_URL` | ✓ | | | Yes | Website URL for emails |
| `REFRESH_TOKEN_SECRET` | | | | Yes | Refresh token secret | | `API_BASE_URL` | | | | Yes | Website-to-API base URL |
| `CONFIRMATION_TOKEN_SECRET` | | | | Yes | Confirmation token secret | | `SESSION_SECRET` | | | | Yes | Website session signing |
| `WEBSITE_BASE_URL` | | | | Yes | Website URL for emails | | `NODE_ENV` | | | | No | Runtime mode |
| **Authentication (Frontend)** | | `CLEAR_DATABASE` | ✓ | | ✓ | No | Dev/test reset flag |
| `CONFIRMATION_TOKEN_SECRET` | | | | Yes | Email confirmation | | `ASPNETCORE_ENVIRONMENT` | | | | Yes | ASP.NET environment |
| `RESET_PASSWORD_TOKEN_SECRET` | | | | Yes | Password reset | | `ASPNETCORE_URLS` | | | | Yes | API binding address |
| `SESSION_SECRET` | | | | Yes | Session signing | | `SA_PASSWORD` | | | | Yes | SQL Server container |
| `SESSION_TOKEN_NAME` | | | | No | Default: "biergarten" | | `ACCEPT_EULA` | | | | Yes | SQL Server EULA |
| `SESSION_MAX_AGE` | | | | No | Default: 604800 | | `MSSQL_PID` | | | | No | SQL Server edition |
| **Base Configuration** | | `DOTNET_RUNNING_IN_CONTAINER` | ✓ | | ✓ | No | Container flag |
| `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 |
\* Either `DB_CONNECTION_STRING` OR the component variables (`DB_SERVER`, `DB_NAME`, \* Either `DB_CONNECTION_STRING` OR the component variables (`DB_SERVER`, `DB_NAME`,
`DB_USER`, `DB_PASSWORD`) must be provided. `DB_USER`, `DB_PASSWORD`) must be provided.
@@ -340,13 +258,12 @@ Variables are validated at startup:
### Frontend Validation ### 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.) - `API_BASE_URL` defaults to `http://localhost:8080`
- Format validation (email, URL patterns) - `SESSION_SECRET` falls back to a development-only local secret
- Required vs optional enforcement - `NODE_ENV` controls secure cookie behavior
**Location**: `src/Website/src/config/env/index.ts`
## Example Configuration Files ## Example Configuration Files
@@ -378,28 +295,10 @@ ACCEPT_EULA=Y
MSSQL_PID=Express MSSQL_PID=Express
``` ```
### `.env.local` (Frontend) ### Frontend local runtime example
```bash ```bash
# Base API_BASE_URL=http://localhost:8080
BASE_URL=http://localhost:3000
NODE_ENV=development
# Authentication
SESSION_SECRET=<generated-with-openssl> SESSION_SECRET=<generated-with-openssl>
NODE_ENV=development
# 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!
``` ```

View File

@@ -1,19 +1,16 @@
# Getting Started # Getting Started
This guide will help you set up and run The Biergarten App in your development This guide covers local setup for the current Biergarten stack: the .NET backend in
environment. `src/Core` and the active React Router frontend in `src/Website`.
## Prerequisites ## 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) ## Recommended Path: Docker for Backend, Node for Frontend
- **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)
### 1. Clone the Repository ### 1. Clone the Repository
@@ -22,174 +19,120 @@ git clone <repository-url>
cd the-biergarten-app cd the-biergarten-app
``` ```
### 2. Configure Environment Variables ### 2. Configure Backend Environment Variables
Copy the example environment file:
```bash ```bash
cp .env.example .env.dev cp .env.example .env.dev
``` ```
Edit `.env.dev` with your configuration: At minimum, ensure `.env.dev` includes valid database and token values:
```bash ```bash
# Database (component-based for Docker)
DB_SERVER=sqlserver,1433 DB_SERVER=sqlserver,1433
DB_NAME=Biergarten DB_NAME=Biergarten
DB_USER=sa DB_USER=sa
DB_PASSWORD=YourStrong!Passw0rd DB_PASSWORD=YourStrong!Passw0rd
ACCESS_TOKEN_SECRET=<generated>
# JWT Authentication REFRESH_TOKEN_SECRET=<generated>
JWT_SECRET=your-secret-key-minimum-32-characters-required CONFIRMATION_TOKEN_SECRET=<generated>
WEBSITE_BASE_URL=http://localhost:3000
``` ```
> For a complete list of environment variables, see See [Environment Variables](environment-variables.md) for the full list.
> [Environment Variables](environment-variables.md).
### 3. Start the Development Environment ### 3. Start the Backend Stack
```bash ```bash
docker compose -f docker-compose.dev.yaml up -d 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 Available endpoints:
- Run database migrations
- Seed initial data
- Start the API on http://localhost:8080
### 4. Access the API - API Swagger: http://localhost:8080/swagger
- Health Check: http://localhost:8080/health
- **Swagger UI**: http://localhost:8080/swagger ### 4. Start the Active Frontend
- **Health Check**: http://localhost:8080/health
### 5. View Logs
```bash ```bash
# All services cd src/Website
docker compose -f docker-compose.dev.yaml logs -f npm install
API_BASE_URL=http://localhost:8080 SESSION_SECRET=dev-secret-change-me npm run dev
# Specific service
docker compose -f docker-compose.dev.yaml logs -f api.core
``` ```
### 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 ```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 docker compose -f docker-compose.dev.yaml down -v
``` ```
## Manual Setup (Without Docker) ### Frontend
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
```bash ```bash
# macOS/Linux cd src/Website
export DB_CONNECTION_STRING="Server=localhost,1433;Database=Biergarten;User Id=sa;Password=YourStrong!Passw0rd;TrustServerCertificate=True;" npm run lint
export JWT_SECRET="your-secret-key-minimum-32-characters-required" npm run typecheck
npm run format:check
# Windows PowerShell npm run test:storybook
$env:DB_CONNECTION_STRING="Server=localhost,1433;Database=Biergarten;User Id=sa;Password=YourStrong!Passw0rd;TrustServerCertificate=True;" npm run test:storybook:playwright
$env:JWT_SECRET="your-secret-key-minimum-32-characters-required"
``` ```
#### 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="<generated>"
export REFRESH_TOKEN_SECRET="<generated>"
export CONFIRMATION_TOKEN_SECRET="<generated>"
export WEBSITE_BASE_URL="http://localhost:3000"
```
### 2. Run Migrations and Seed
```bash ```bash
cd src/Core cd src/Core
dotnet run --project Database/Database.Migrations/Database.Migrations.csproj dotnet run --project Database/Database.Migrations/Database.Migrations.csproj
```
#### 4. Seed the Database
```bash
dotnet run --project Database/Database.Seed/Database.Seed.csproj dotnet run --project Database/Database.Seed/Database.Seed.csproj
``` ```
#### 5. Start the API ### 3. Start the API
```bash ```bash
dotnet run --project API/API.Core/API.Core.csproj dotnet run --project API/API.Core/API.Core.csproj
``` ```
The API will be available at http://localhost:5000 (or the port specified in ## Legacy Frontend Note
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.
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 ## Next Steps
- **Test the API**: Visit http://localhost:8080/swagger and try the endpoints - Review [Architecture](architecture.md)
- **Run Tests**: See [Testing Guide](testing.md) - Run backend and frontend checks from [Testing](testing.md)
- **Learn the Architecture**: Read [Architecture Overview](architecture.md) - Use [Docker Guide](docker.md) for container troubleshooting
- **Understand Docker Setup**: See [Docker Guide](docker.md)
- **Database Details**: Check [Database Schema](database.md)

View File

@@ -4,11 +4,13 @@ This document describes the testing strategy and how to run tests for The Bierga
## Overview ## 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) - **API.Specs** - BDD integration tests using Reqnroll (Gherkin)
- **Infrastructure.Repository.Tests** - Unit tests for data access layer - **Infrastructure.Repository.Tests** - Unit tests for data access layer
- **Service.Auth.Tests** - Unit tests for authentication business logic - **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) ## 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) - 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 ## Test Coverage
### Current Coverage ### Current Coverage
@@ -112,6 +141,14 @@ dotnet test Service/Service.Auth.Tests/Service.Auth.Tests.csproj
- Register service with validation - Register service with validation
- Business logic for authentication flow - 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 ### Planned Coverage
- [ ] Email verification workflow - [ ] Email verification workflow
@@ -121,6 +158,7 @@ dotnet test Service/Service.Auth.Tests/Service.Auth.Tests.csproj
- [ ] Beer post operations - [ ] Beer post operations
- [ ] User follow/unfollow - [ ] User follow/unfollow
- [ ] Image upload service - [ ] Image upload service
- [ ] Frontend route integration coverage beyond Storybook stories
## Testing Frameworks & Tools ## Testing Frameworks & Tools
@@ -254,6 +292,15 @@ Exit codes:
- `0` - All tests passed - `0` - All tests passed
- Non-zero - Test failures occurred - 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 ## Troubleshooting
### Tests Failing Due to Database Connection ### Tests Failing Due to Database Connection