All checks were successful
Test Asgard Runner / test (push) Successful in 3s
Real @Public() NestJS endpoint persisting to the existing early_access_signups table (email + server_count), matching the schema exactly (no migration). Duplicate-email safe (pre-check + unique-constraint catch -> friendly success). Wired into app.module. Makes the marketing early-access form functional end-to-end on next API deploy. tsc/nest build green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
43 lines
1.4 KiB
TypeScript
43 lines
1.4 KiB
TypeScript
import { Injectable, Logger } from '@nestjs/common';
|
|
import { InjectRepository } from '@nestjs/typeorm';
|
|
import { Repository } from 'typeorm';
|
|
import { EarlyAccessSignup } from '../../entities/early-access-signup.entity';
|
|
import { CreateEarlyAccessDto } from './dto/create-early-access.dto';
|
|
|
|
@Injectable()
|
|
export class EarlyAccessService {
|
|
private readonly logger = new Logger(EarlyAccessService.name);
|
|
|
|
constructor(
|
|
@InjectRepository(EarlyAccessSignup)
|
|
private readonly repo: Repository<EarlyAccessSignup>,
|
|
) {}
|
|
|
|
async register(dto: CreateEarlyAccessDto): Promise<{ success: true; alreadyRegistered: boolean }> {
|
|
const existing = await this.repo.findOne({ where: { email: dto.email } });
|
|
if (existing) {
|
|
// Duplicate email — return friendly success rather than a 409 that would break the UX
|
|
return { success: true, alreadyRegistered: true };
|
|
}
|
|
|
|
const signup = this.repo.create({
|
|
email: dto.email,
|
|
server_count: dto.server_count ?? 'not specified',
|
|
});
|
|
|
|
try {
|
|
await this.repo.save(signup);
|
|
} catch (err: unknown) {
|
|
// Guard against a race-condition duplicate (unique constraint violation)
|
|
const pg = err as { code?: string };
|
|
if (pg.code === '23505') {
|
|
return { success: true, alreadyRegistered: true };
|
|
}
|
|
this.logger.error('Failed to save early-access signup', err);
|
|
throw err;
|
|
}
|
|
|
|
return { success: true, alreadyRegistered: false };
|
|
}
|
|
}
|