feat(core): consolidate auth service into backend and implement stripe billing
CI / Frontend (push) Successful in 9m54s
CI / Go - apps/auth-service (push) Failing after 24s
CI / Go - apps/backend (push) Failing after 5m43s
CI / Docker publish - auth-service (push) Has been skipped
CI / Docker publish - backend (push) Has been skipped

This commit performs a major architectural refactor by migrating the standalone `auth-service` into the main `backend` application, enabling a unified codebase and simplified deployment. It also introduces comprehensive Stripe billing support and a new administrative dashboard.

Key changes:
- **Architecture**: Deleted `apps/auth-service` and integrated its functionality (JWT, magic links, OAuth, user management) into `apps/backend`.
- **Billing**: Added Stripe integration to `backend`, supporting both monthly and yearly subscription cycles with automatic plan entitlement enforcement (e.g., location limits).
- **Admin Dashboard**: Implemented a new administrative service and API endpoints to manage tenants, users, and view platform-wide statistics.
- **Frontend**:
    - Added a new pricing page with monthly/yearly toggle and comparison table.
    - Integrated Stripe and Sentry for payments and error tracking.
    - Improved dashboard UX/UI and added i18n support for new features.
    - Enhanced the public booking flow with better validation and contact form integration.
- **Database**: Added migrations for users, magic links, password resets, OAuth states, admin audit logs, and refresh tokens.
- **DevOps**: Updated environment configurations for Railway and Vercel, and streamlined the project's `package.json` scripts.
This commit is contained in:
Tomas Dvorak
2026-05-09 18:25:25 +02:00
parent cf3315e8fc
commit 164a37e997
69 changed files with 4630 additions and 5260 deletions
+140 -10
View File
@@ -13,6 +13,7 @@ const dictionaries = {
// Navigation & Auth
"nav.booking": "Veřejná rezervace",
"nav.dashboard": "Aplikace",
"nav.pricing": "Ceník",
"nav.about": "O nás",
"nav.contact": "Kontakt",
@@ -164,6 +165,26 @@ const dictionaries = {
"home.pricing.biz.cta": "Kontaktovat prodej",
"home.pricing.biz.trial": "Individuální řešení na míru",
// Comparison
"pricing.compare.eyebrow": "Detailní srovnání",
"pricing.compare.title": "Porovnání plánů",
"pricing.compare.feature": "Funkce",
"pricing.compare.locations": "Lokace",
"pricing.compare.staff": "Zaměstnanci",
"pricing.compare.bookings": "Rezervací/měsíc",
"pricing.compare.emailSupport": "E-mailová podpora",
"pricing.compare.reminders": "E-mailová připomenutí",
"pricing.compare.analytics": "Analytika",
"pricing.compare.api": "API přístup",
"pricing.compare.branding": "Vlastní branding",
"pricing.compare.whiteLabel": "Bílý labeling",
"pricing.compare.manager": "Dedikovaný manažer",
"pricing.compare.priority": "Prioritní",
"pricing.compare.dedicated": "Dedikovaný",
"pricing.compare.advanced": "Pokročilá",
"pricing.compare.yes": "Ano",
"pricing.compare.no": "Ne",
// CTA
"home.cta.title": "Připraveni zjednodušit své rezervace?",
"home.cta.subtitle": "Připojte se k tisícům podniků, které šetří čas s Bookra.",
@@ -235,12 +256,51 @@ const dictionaries = {
"footer.links.title": "Navigace",
"footer.legal.title": "Právní informace",
// Dashboard (existing)
// Dashboard
"dashboard.title": "Přehled podniku",
"dashboard.body": "Sledujte rezervace, nastavení, předplatné a rezervační widget na jednom místě.",
"dashboard.kpi.bookings": "Rezervace tento týden",
"dashboard.kpi.cancellations": "Zrušení",
"dashboard.kpi.utilization": "Vytížení",
"dashboard.overview": "Přehled",
"dashboard.bookings": "Rezervace",
"dashboard.customers": "Zákazníci",
"dashboard.zones": "Zóny a dostupnost",
"dashboard.billing": "Platby",
"dashboard.settings": "Nastavení",
"dashboard.welcome": "Dobrý den,",
"dashboard.overviewFor": "Přehled pro",
"dashboard.kpi.bookings": "Celkem rezervací",
"dashboard.kpi.cancelled": "Zrušených",
"dashboard.kpi.completed": "Dokončených",
"dashboard.kpi.newClients": "Noví klienti",
"dashboard.recentActivity": "Nedávná aktivita",
"dashboard.upcomingBookings": "Nadcházející rezervace",
"dashboard.viewAll": "Zobrazit vše",
"dashboard.locationLimitReached": "Dosáhli jste limitu lokací!",
"dashboard.nearingLocationLimit": "Blížíte se limitu lokací",
"dashboard.locationsUsed": "lokací použito",
"dashboard.upgrade": "Upgrade",
"dashboard.shareManage": "Sdílet/Spravit",
"dashboard.notifications": "Oznámení",
"dashboard.bookingManagement": "Správa rezervací",
"dashboard.totalBookings": "celkem rezervací",
"dashboard.newBooking": "Nová rezervace",
"dashboard.bookingDetails": "Detail rezervace",
"dashboard.customerDetails": "Detail zákazníka",
"dashboard.close": "Zavřít",
"dashboard.edit": "Upravit",
"dashboard.cancel": "Zrušit",
"dashboard.details": "Detail",
"dashboard.saveChanges": "Uložit změny",
"dashboard.createBooking": "Vytvořit rezervaci",
"dashboard.preview": "Zobrazit náhled",
"dashboard.saveEmailSettings": "Uložit nastavení emailů",
"dashboard.saving": "Ukládání...",
"dashboard.creating": "Vytváření...",
"dashboard.prevMonth": "Předchozí měsíc",
"dashboard.nextMonth": "Další měsíc",
"dashboard.confirmed": "Potvrzeno",
"dashboard.pending": "Čeká",
"dashboard.cancelled": "Zrušeno",
"dashboard.completed": "Dokončeno",
"dashboard.welcome.title": "Vítejte v Bookra",
"dashboard.welcome.body": "Zjednodušte své rezervace a mějte více času na to, co vás baví.",
"dashboard.authRequired": "Pro vstup do aplikace se přihlaste nebo si vytvořte účet.",
@@ -248,7 +308,6 @@ const dictionaries = {
"dashboard.liveData": "Živá data",
"dashboard.liveDataBody": "Dashboard, nastavení a předplatné se načítají z API pro přihlášený účet.",
"dashboard.apiReady": "API připojení aktivní",
"dashboard.billing": "Předplatné",
"dashboard.checkout": "Otevřít platbu",
"dashboard.refreshBilling": "Obnovit předplatné",
"dashboard.plan": "Plán",
@@ -326,6 +385,12 @@ const dictionaries = {
"contact.info.email.desc": "Preferujete psát? Jsme tu pro vás.",
"contact.info.hours.title": "Pracovní doba",
"contact.info.hours.desc": "Odpovídáme během pracovních dní 9:00 — 17:00 CET.",
"contact.story.heading": "Proč nás kontaktovat?",
"contact.story.p1": "Ať už máte dotaz ohledně funkcí, potřebujete pomoci s nastavením, nebo chcete sdílet zpětnou vazbu — rádi vám pomůžeme.",
"contact.story.p2": "Naším cílem je, aby správa rezervací byla pro vás bezstarostná. Ozvěte se nám a najdeme řešení společně.",
"contact.error.title": "Nepodařilo se odeslat",
"contact.error.body": "Zkuste to prosím později, nebo nám napište přímo na hello@bookra.eu.",
"contact.email.address": "hello@bookra.eu",
// Legal
"legal.privacy.title": "Ochrana soukromí",
@@ -345,6 +410,7 @@ const dictionaries = {
// Navigation & Auth
"nav.booking": "Public booking",
"nav.dashboard": "App",
"nav.pricing": "Pricing",
"nav.about": "About us",
"nav.contact": "Contact",
@@ -496,6 +562,26 @@ const dictionaries = {
"home.pricing.biz.cta": "Contact sales",
"home.pricing.biz.trial": "Custom enterprise solutions",
// Comparison
"pricing.compare.eyebrow": "Detailed comparison",
"pricing.compare.title": "Compare plans",
"pricing.compare.feature": "Feature",
"pricing.compare.locations": "Locations",
"pricing.compare.staff": "Staff members",
"pricing.compare.bookings": "Bookings/month",
"pricing.compare.emailSupport": "Email support",
"pricing.compare.reminders": "Email reminders",
"pricing.compare.analytics": "Analytics",
"pricing.compare.api": "API access",
"pricing.compare.branding": "Custom branding",
"pricing.compare.whiteLabel": "White labeling",
"pricing.compare.manager": "Dedicated manager",
"pricing.compare.priority": "Priority",
"pricing.compare.dedicated": "Dedicated",
"pricing.compare.advanced": "Advanced",
"pricing.compare.yes": "Yes",
"pricing.compare.no": "No",
// CTA
"home.cta.title": "Ready to simplify your bookings?",
"home.cta.subtitle": "Join thousands of businesses saving time with Bookra.",
@@ -567,12 +653,51 @@ const dictionaries = {
"footer.links.title": "Navigation",
"footer.legal.title": "Legal",
// Dashboard (existing)
// Dashboard
"dashboard.title": "Owner dashboard",
"dashboard.body": "Track weekly bookings, cancellations, utilization, and subscription state with a tenant-aware shell ready for Neon-backed data.",
"dashboard.kpi.bookings": "Bookings this week",
"dashboard.kpi.cancellations": "Cancellations",
"dashboard.kpi.utilization": "Utilization",
"dashboard.overview": "Overview",
"dashboard.bookings": "Bookings",
"dashboard.customers": "Customers",
"dashboard.zones": "Zones & Availability",
"dashboard.billing": "Billing",
"dashboard.settings": "Settings",
"dashboard.welcome": "Welcome back,",
"dashboard.overviewFor": "Overview for",
"dashboard.kpi.bookings": "Total Bookings",
"dashboard.kpi.cancelled": "Cancelled",
"dashboard.kpi.completed": "Completed",
"dashboard.kpi.newClients": "New Clients",
"dashboard.recentActivity": "Recent Activity",
"dashboard.upcomingBookings": "Upcoming Bookings",
"dashboard.viewAll": "View all",
"dashboard.locationLimitReached": "You've reached your location limit!",
"dashboard.nearingLocationLimit": "You're nearing your location limit",
"dashboard.locationsUsed": "locations used",
"dashboard.upgrade": "Upgrade",
"dashboard.shareManage": "Share/Manage",
"dashboard.notifications": "Notifications",
"dashboard.bookingManagement": "Booking Management",
"dashboard.totalBookings": "total bookings",
"dashboard.newBooking": "New Booking",
"dashboard.bookingDetails": "Booking Details",
"dashboard.customerDetails": "Customer Details",
"dashboard.close": "Close",
"dashboard.edit": "Edit",
"dashboard.cancel": "Cancel",
"dashboard.details": "Details",
"dashboard.saveChanges": "Save Changes",
"dashboard.createBooking": "Create Booking",
"dashboard.preview": "Preview",
"dashboard.saveEmailSettings": "Save Email Settings",
"dashboard.saving": "Saving...",
"dashboard.creating": "Creating...",
"dashboard.prevMonth": "Previous month",
"dashboard.nextMonth": "Next month",
"dashboard.confirmed": "Confirmed",
"dashboard.pending": "Pending",
"dashboard.cancelled": "Cancelled",
"dashboard.completed": "Completed",
"dashboard.welcome.title": "Welcome to Bookra",
"dashboard.welcome.body": "Simplify your bookings and spend more time doing what you love.",
"dashboard.authRequired": "Live dashboard data needs a Neon Auth session and JWT.",
@@ -580,7 +705,6 @@ const dictionaries = {
"dashboard.liveData": "Live data",
"dashboard.liveDataBody": "Dashboard, tenant, and billing data are loaded from the API for the signed-in workspace.",
"dashboard.apiReady": "API connection active",
"dashboard.billing": "Billing",
"dashboard.checkout": "Open checkout",
"dashboard.refreshBilling": "Refresh billing",
"dashboard.plan": "Plan",
@@ -658,6 +782,12 @@ const dictionaries = {
"contact.info.email.desc": "Prefer to write? We're here for you.",
"contact.info.hours.title": "Working hours",
"contact.info.hours.desc": "We respond on business days 9:00 — 17:00 CET.",
"contact.story.heading": "Why reach out?",
"contact.story.p1": "Whether you have questions about features, need help with setup, or want to share feedback — we're happy to help.",
"contact.story.p2": "Our goal is to make booking management effortless for you. Get in touch and we'll find a solution together.",
"contact.error.title": "Failed to send",
"contact.error.body": "Please try again later, or email us directly at hello@bookra.eu.",
"contact.email.address": "hello@bookra.eu",
// Legal
"legal.privacy.title": "Privacy",