regatta.club Document Generator, a professional application for race committees to compose Notices of Race (NoR) and Sailing Instructions (SI) documents.
This application only works if you configure an OIDC authentication provider: You can use Authentik, Keycloak, or anything else that supports OIDC and custom claims.
- Copy .env.example to .env and modify it according to your environment, or use its environment variables directly in your
docker runstatement/docker-compose.yml. ‼️ Mount whatever database path you define in theDATABASE_PATHenvironment variable as a volume to persist data- Create an application in your authentication provider, and make sure it delivers the claim you define as
OIDC_RACE_COMMITTEE_CLAIM, and, optionally, what you define inOIDC_RACE_COMMITTEE_LOGO_CLAIM. The following is required to be able to save document sets in the application: TheOIDC_RACE_COMMITTEE_CLAIMmust be set to a claim, say,race_committee, that your identity provider can deliver for each user with the value of how the user's race committee is called. TheOIDC_RACE_COMMITTEE_LOGO_CLAIMis optional - it allows a custom, race committee specific logo url to be retrieved from the identity provider. - If your identity provider needs the client to request a scope to get access to the above claim, you have to add it to
OIDC_SCOPE, it's a space-separated list of scopes, for exampleOIDC_SCOPE=openid profile email race_committee. - Set
OIDC_USER_CLAIMto one that returns a legible user name. Uniqueness is only critical for users in the same race committee.OIDC_USER_CLAIM=preferred_usernameshould generally therefore be fine. If you want more uniqueness, feel free to useOIDC_USER_CLAIM=emailorOIDC_USER_CLAIM=sub. The user's full name is currently read from thenameclaim by default.
The application does intentionally not include user management. It completely relies on you defining an external OIDC identity source. Membership of users to race committees is solely defined by making that identity source return the right value for your
OIDC_RACE_COMMITTEE_CLAIMper user. It's up to your configuration of the OIDC identity provider to resolve groups to that claim, or similar. If you have users that are members of more than one race committee, you will have to define a flow in your identity provider that allows them to select a race committee while authenticating. Authentik, Keycloak, and, with a bit of coding, Zitadel can do this just fine.
Here's a docker-compose.yml you could use:
volumes:
data:
services:
app:
image: christianstrauch/rc-docgen:latest
volumes:
- data:/app/data
environment:
- "DATABASE_PATH=/app/data/regatta.db"
# OIDC Authentication Configuration
# The application will automatically discover endpoints from OIDC_ISSUER/.well-known/openid-configuration
- "OIDC_ISSUER=https://your-oidc-provider.com"
- "OIDC_CLIENT_ID=your-client-id"
- "OIDC_CLIENT_SECRET=your-client-secret"
- "OIDC_CALLBACK_URL=http://your-app-url:3000/api/auth/callback"
- "OIDC_SCOPE=openid profile email"
- "OIDC_USER_ID_CLAIM=sub"
- "OIDC_RACE_COMMITTEE_CLAIM=org"
- "OIDC_RACE_COMMITTEE_LOGO_CLAIM="
# Default logo URL used when no race committee-specific logo is provided
- "LOGO_URL=https://example.com/logo.png"
- "APP_NAME=My Race Document Set Generator"
- "NODE_ENV=production"Here's what the application includes:
- Basic info (title, venue, dates, organizer)
- Communication (VHF channel)
- Entry & fees
- Awards ceremony details
- Technical requirements (scoring, certificates, time limits)
- Contact information
- Racing Rules of Sailing 2025-2028
- US Sailing Prescriptions
- Appendices (T, P, V1, etc.)
- Rules organized by category with accordion interface
- Ability to select rules that only apply if specifically mentioned
- Inline text modification for customizing rules
- Visual indicators for modified rules
- Separate selection for NoR and SI documents
- Add unlimited custom sections
- Pre-suggested common fields (Restricted Areas, Safety Requirements, etc.)
- Free-text input for custom content
- Side-by-side preview of NoR and SI documents
- Properly formatted markdown with numbered sections
- Download as .md files
- Copy to clipboard functionality
- Documents follow standard sailing regatta format based on the provided examples
- Nautical-themed color palette (blues and ocean colors)
- Clean, professional interface inspired by documentation sites
- Responsive layout
- Tab-based navigation for workflow
- Toast notifications for user feedback
The application intelligently separates rules into NoR and SI based on their typical usage, allows modifications to rule text (with visual indicators), and generates properly formatted markdown documents ready for publication.
- SQLite database with proper schema for race committees and regatta documents
- Database utilities for CRUD operations with proper access control
- Complete OIDC integration with configurable provider settings
- User session management with JWT verification
- Race committee identification via configurable OIDC claims
- Login/logout flows with secure session cookies
- Fleet manager component to add/remove fleets
- Fleet-specific provisions that can apply to NoR, SI, or both
- Color-coded fleet visualization
- Support for conditional rules per fleet (e.g., autopilots for single-handed sailors)
- Save documents to database under user's race committee
- Load existing documents from dropdown selector
- Modify and update saved documents
- Row-level security ensuring users only see their committee's documents
- New document creation functionality
- Markdown to HTML conversion using 'marked' library
- Opens formatted documents in new browser window with professional styling
- Printable HTML output
- Maintains markdown download and clipboard copy features
- Logo URL configuration
- App name customization
- All OIDC settings (issuer, client ID/secret, callback URL, claim mappings)
- Database path configuration
- Complete Dockerfile with multi-stage build
- Automatic database initialization on container start
- Proper volume mounts for persistent data
- Optimized for production deployment