mirror of
https://github.com/fluxerapp/fluxer
synced 2026-10-18 21:45:31 +09:00
chore(repo): prune dead code and duplicate abstractions (#3413)
This commit is contained in:
1 parent
c17091768c
commit
c9fdf8fead
2937 files changed
+42233
-176793
No files matched your search
@@ -38,26 +38,6 @@ export class Donor {
|
||||
this.version = row.version;
|
||||
}
|
||||
|
||||
toRow(): DonorRow {
|
||||
return {
|
||||
email: this.email,
|
||||
stripe_customer_id: this.stripeCustomerId,
|
||||
business_name: this.businessName,
|
||||
tax_id: this.taxId,
|
||||
tax_id_type: this.taxIdType,
|
||||
stripe_subscription_id: this.stripeSubscriptionId,
|
||||
subscription_amount_cents: this.subscriptionAmountCents,
|
||||
subscription_currency: this.subscriptionCurrency,
|
||||
subscription_interval: this.subscriptionInterval,
|
||||
subscription_current_period_end: this.subscriptionCurrentPeriodEnd,
|
||||
subscription_cancel_at: this.subscriptionCancelAt,
|
||||
subscription_status: this.subscriptionStatus,
|
||||
created_at: this.createdAt,
|
||||
updated_at: this.updatedAt,
|
||||
version: this.version,
|
||||
};
|
||||
}
|
||||
|
||||
hasActiveSubscription(): boolean {
|
||||
if (!this.stripeSubscriptionId || !this.subscriptionCurrentPeriodEnd) {
|
||||
return false;
|
||||
|
||||
@@ -3,10 +3,9 @@
|
||||
import {Config} from '@app/api/Config';
|
||||
import {getContentMessage} from '@app/api/content_i18n/ContentI18n';
|
||||
import type {DonationRepository} from '@app/api/donation/DonationRepository';
|
||||
import type {IEmailDnsValidationService} from '@app/api/infrastructure/IEmailDnsValidationService';
|
||||
import type {EmailDnsValidationService} from '@app/api/infrastructure/EmailDnsValidationService';
|
||||
import {getInstanceProductName} from '@app/api/instance/ProductName';
|
||||
import {Logger} from '@app/api/Logger';
|
||||
import {getBillingRepository} from '@app/api/middleware/ServiceRegistry';
|
||||
import {shouldDisableAdaptivePricing} from '@app/api/utils/CurrencyUtils';
|
||||
import {ValidationErrorCodes} from '@fluxer/constants/src/ValidationErrorCodes';
|
||||
import {InputValidationError} from '@fluxer/errors/src/domains/core/InputValidationError';
|
||||
@@ -98,7 +97,7 @@ export class DonationCheckoutService {
|
||||
constructor(
|
||||
private stripe: Stripe | null,
|
||||
private donationRepository: DonationRepository,
|
||||
private emailDnsValidationService: IEmailDnsValidationService,
|
||||
private emailDnsValidationService: EmailDnsValidationService,
|
||||
) {}
|
||||
|
||||
async createCheckout(params: {
|
||||
@@ -203,14 +202,6 @@ export class DonationCheckoutService {
|
||||
sessionParams.customer_email = params.email;
|
||||
session = await this.stripe.checkout.sessions.create(sessionParams);
|
||||
}
|
||||
try {
|
||||
await getBillingRepository().checkoutSessions.upsertFromStripe(session);
|
||||
} catch (mirrorErr) {
|
||||
Logger.error(
|
||||
{mirrorErr, sessionId: session.id},
|
||||
'Mirror upsert failed after Stripe write; reconciler will heal',
|
||||
);
|
||||
}
|
||||
if (!session.url) {
|
||||
throw new StripeError('Failed to create checkout session');
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import {randomBytes} from 'node:crypto';
|
||||
import {Config} from '@app/api/Config';
|
||||
import type {DonationRepository} from '@app/api/donation/DonationRepository';
|
||||
import {DonorMagicLinkToken} from '@app/api/donation/models/DonorMagicLinkToken';
|
||||
import type {IEmailDnsValidationService} from '@app/api/infrastructure/IEmailDnsValidationService';
|
||||
import type {EmailDnsValidationService} from '@app/api/infrastructure/EmailDnsValidationService';
|
||||
import {Logger} from '@app/api/Logger';
|
||||
import {DONATION_MAGIC_LINK_EXPIRY_MS} from '@fluxer/constants/src/DonationConstants';
|
||||
import {ValidationErrorCodes} from '@fluxer/constants/src/ValidationErrorCodes';
|
||||
@@ -18,7 +18,7 @@ export class DonationMagicLinkService {
|
||||
constructor(
|
||||
private donationRepository: DonationRepository,
|
||||
private emailService: IEmailService,
|
||||
private emailDnsValidationService: IEmailDnsValidationService,
|
||||
private emailDnsValidationService: EmailDnsValidationService,
|
||||
) {}
|
||||
|
||||
async sendMagicLink(email: string, locale: string | null = null): Promise<void> {
|
||||
|
||||
@@ -102,19 +102,9 @@ describe('GET and POST /donations/manage', () => {
|
||||
async function createValidMagicLinkToken(email: string, token: string): Promise<void> {
|
||||
await createMagicLinkToken(email, token, new Date(Date.now() + 15 * 60 * 1000), null);
|
||||
}
|
||||
async function createExpiredMagicLinkToken(email: string, token: string): Promise<void> {
|
||||
await createMagicLinkToken(email, token, new Date(Date.now() - 1000), null);
|
||||
}
|
||||
async function createUsedMagicLinkToken(email: string, token: string): Promise<void> {
|
||||
await createMagicLinkToken(email, token, new Date(Date.now() + 15 * 60 * 1000), new Date(Date.now() - 5000));
|
||||
}
|
||||
describe('GET with a valid token and customer ID', () => {
|
||||
test('redirects to the confirmation page', async () => {
|
||||
await createDonorWithCustomerId(TEST_DONOR_EMAIL, 'cus_test_valid_123');
|
||||
await createValidMagicLinkToken(TEST_DONOR_EMAIL, TEST_MAGIC_LINK_TOKEN);
|
||||
expect(await openManageLink(TEST_MAGIC_LINK_TOKEN)).toBe(confirmUrl(TEST_MAGIC_LINK_TOKEN));
|
||||
});
|
||||
});
|
||||
describe('link scanner prefetch', () => {
|
||||
test('GET does not mark token as used', async () => {
|
||||
await createDonorWithCustomerId(TEST_DONOR_EMAIL, 'cus_test_prefetch');
|
||||
@@ -143,16 +133,6 @@ describe('GET and POST /donations/manage', () => {
|
||||
expect(await isTokenUsed(TEST_MAGIC_LINK_TOKEN)).toBe(true);
|
||||
});
|
||||
});
|
||||
describe('POST with a valid token and customer ID', () => {
|
||||
test('redirects to Stripe billing portal', async () => {
|
||||
const customerId = 'cus_test_valid_123';
|
||||
await createDonorWithCustomerId(TEST_DONOR_EMAIL, customerId);
|
||||
await createValidMagicLinkToken(TEST_DONOR_EMAIL, TEST_MAGIC_LINK_TOKEN);
|
||||
expect(await redeemManageLink(TEST_MAGIC_LINK_TOKEN)).toMatch(STRIPE_PORTAL_URL_PATTERN);
|
||||
expect(stripeHandlers.spies.createdPortalSessions).toHaveLength(1);
|
||||
expect(stripeHandlers.spies.createdPortalSessions[0]?.customer).toBe(customerId);
|
||||
});
|
||||
});
|
||||
describe('valid token without customer ID', () => {
|
||||
test('redirects to no_customer alert when donor has no customer ID', async () => {
|
||||
await createDonorWithoutSubscription(TEST_DONOR_EMAIL, null);
|
||||
@@ -174,22 +154,6 @@ describe('GET and POST /donations/manage', () => {
|
||||
expect(await isTokenUsed(TEST_MAGIC_LINK_TOKEN)).toBe(false);
|
||||
});
|
||||
});
|
||||
describe('expired token handling', () => {
|
||||
test('rejects expired token', async () => {
|
||||
await createDonorWithCustomerId(TEST_DONOR_EMAIL, 'cus_test_expired');
|
||||
await createExpiredMagicLinkToken(TEST_DONOR_EMAIL, TEST_MAGIC_LINK_TOKEN);
|
||||
expect(await openManageLink(TEST_MAGIC_LINK_TOKEN)).toBe(alertUrl('link_expired'));
|
||||
expect(await redeemManageLink(TEST_MAGIC_LINK_TOKEN)).toBe(alertUrl('link_expired'));
|
||||
expect(stripeHandlers.spies.createdPortalSessions).toHaveLength(0);
|
||||
});
|
||||
test('does not mark expired token as used', async () => {
|
||||
await createDonorWithCustomerId(TEST_DONOR_EMAIL, 'cus_test');
|
||||
await createExpiredMagicLinkToken(TEST_DONOR_EMAIL, TEST_MAGIC_LINK_TOKEN);
|
||||
await openManageLink(TEST_MAGIC_LINK_TOKEN);
|
||||
await redeemManageLink(TEST_MAGIC_LINK_TOKEN);
|
||||
expect(await isTokenUsed(TEST_MAGIC_LINK_TOKEN)).toBe(false);
|
||||
});
|
||||
});
|
||||
describe('used token handling', () => {
|
||||
test('rejects already-used token', async () => {
|
||||
await createDonorWithCustomerId(TEST_DONOR_EMAIL, 'cus_test_used');
|
||||
@@ -215,19 +179,6 @@ describe('GET and POST /donations/manage', () => {
|
||||
});
|
||||
});
|
||||
describe('Stripe portal session creation', () => {
|
||||
test('handles Stripe API failure gracefully', async () => {
|
||||
await createDonorWithCustomerId(TEST_DONOR_EMAIL, 'cus_test_stripe_fail');
|
||||
await createValidMagicLinkToken(TEST_DONOR_EMAIL, TEST_MAGIC_LINK_TOKEN);
|
||||
useFailingPortalHandlers();
|
||||
expect(await redeemManageLink(TEST_MAGIC_LINK_TOKEN)).toBe(alertUrl('portal_error'));
|
||||
});
|
||||
test('does not mark token as used when the portal session fails', async () => {
|
||||
await createDonorWithCustomerId(TEST_DONOR_EMAIL, 'cus_test_stripe_fail');
|
||||
await createValidMagicLinkToken(TEST_DONOR_EMAIL, TEST_MAGIC_LINK_TOKEN);
|
||||
useFailingPortalHandlers();
|
||||
await redeemManageLink(TEST_MAGIC_LINK_TOKEN);
|
||||
expect(await isTokenUsed(TEST_MAGIC_LINK_TOKEN)).toBe(false);
|
||||
});
|
||||
test('redeems the same token once Stripe recovers', async () => {
|
||||
const customerId = 'cus_test_stripe_retry';
|
||||
await createDonorWithCustomerId(TEST_DONOR_EMAIL, customerId);
|
||||
|
||||
@@ -56,16 +56,4 @@ describe('POST /donations/request-link', () => {
|
||||
expect(token).toMatch(/^[0-9a-f]{64}$/);
|
||||
});
|
||||
});
|
||||
describe('idempotency', () => {
|
||||
test('generates new token on each request, invalidating previous ones', async () => {
|
||||
await createDonor(TEST_DONOR_EMAIL);
|
||||
await createDonationRequestLinkBuilder(harness).body({email: TEST_DONOR_EMAIL}).expect(204).execute();
|
||||
await createDonationRequestLinkBuilder(harness).body({email: TEST_DONOR_EMAIL}).expect(204).execute();
|
||||
const emails = await listTestEmails(harness, {recipient: TEST_DONOR_EMAIL});
|
||||
expect(emails).toHaveLength(2);
|
||||
const token1 = emails[0]?.metadata.token;
|
||||
const token2 = emails[1]?.metadata.token;
|
||||
expect(token1).not.toBe(token2);
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user