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
+53 -9
View File
@@ -232,23 +232,57 @@ export interface components {
primaryColor?: string;
siteUrl?: string;
};
/**
* @description Checkout launch response supporting both Stripe and Paddle providers.
* For Stripe: checkoutUrl is returned (redirect-based checkout).
* For Paddle: priceId, customerId, customerEmail, customData are returned (client-side checkout).
*/
CheckoutLaunchResponse: {
/** Format: uri */
cancelRedirectUrl: string;
customData: {
/**
* Format: uri
* @description URL to redirect after cancelled checkout
*/
cancelRedirectUrl?: string;
/**
* Format: uri
* @description Stripe checkout URL (redirect the user to this URL)
*/
checkoutUrl?: string;
/** @description Custom metadata for Paddle checkout */
customData?: {
[key: string]: string;
};
/** Format: email */
/**
* Format: email
* @description Customer email for Paddle checkout
*/
customerEmail?: string;
/** @description Paddle customer ID */
customerId?: string;
priceId: string;
/** Format: uri */
successRedirectUrl: string;
/** @description Paddle price ID for client-side checkout */
priceId?: string;
/**
* Format: uri
* @description URL to redirect after successful checkout
*/
successRedirectUrl?: string;
};
CheckoutSessionRequest: {
/** @enum {string} */
/**
* @description Billing interval. Yearly gets 17% discount.
* @default monthly
* @enum {string}
*/
billingInterval: "monthly" | "yearly";
/**
* @description Currency for the subscription
* @enum {string}
*/
currency?: "czk" | "usd";
/** @enum {string} */
/**
* @description The plan to subscribe to
* @enum {string}
*/
planCode: "starter" | "pro" | "business";
};
CreateBookingRequest: {
@@ -327,10 +361,20 @@ export interface components {
timezone: string;
};
PlanDisplayPrice: {
/** @description Monthly price in cents */
amountCents: number;
/** @enum {string} */
currency: "czk" | "usd";
/** @description Formatted monthly price string */
formatted: string;
/** @description Yearly price in cents (17% discount) */
yearlyAmountCents?: number;
/** @description Formatted yearly price string */
yearlyFormatted?: string;
/** @description Description of yearly savings */
yearlySavings?: string;
/** @description Percentage saved with yearly billing */
yearlySavingsPercent?: number;
};
PlanEntitlements: {
advancedReporting: boolean;