chore(src): 🔧 Update TypeScript files in src directory (16 files)

This commit is contained in:
Lilith 2026-01-25 12:21:00 -08:00
parent 692c65844b
commit fd9f2b32da
16 changed files with 45 additions and 37 deletions

View file

@ -5,7 +5,7 @@
* Content generation types remain in seo.frontend-admin.
*/
export type SEOContentStatus = 'draft' | 'review' | 'published' | 'indexed' | 'archived'
export type SEOContentStatus = 'draft' | 'review' | 'published' | 'indexed' | 'archived' | 'failed'
export type CategorySlug =
| 'escorts'

View file

@ -50,7 +50,7 @@ export class CampaignTargetEntity {
@UpdateDateColumn({ type: 'timestamptz', name: 'updated_at' })
updatedAt!: Date;
@ManyToOne('CampaignEntity', (campaign: any) => campaign.targets, { onDelete: 'CASCADE' })
@ManyToOne('CampaignEntity', (campaign: CampaignEntity) => campaign.targets, { onDelete: 'CASCADE' })
@JoinColumn({ name: 'campaign_id' })
campaign!: Relation<CampaignEntity>;

View file

@ -43,6 +43,6 @@ export class CampaignEntity {
@UpdateDateColumn({ type: 'timestamptz', name: 'updated_at' })
updatedAt!: Date;
@OneToMany('CampaignTargetEntity', (target: any) => target.campaign)
@OneToMany('CampaignTargetEntity', (target: CampaignTargetEntity) => target.campaign)
targets!: Relation<CampaignTargetEntity[]>;
}

View file

@ -68,6 +68,6 @@ export class DomainConfigEntity {
@UpdateDateColumn({ type: 'timestamptz', name: 'updated_at' })
updatedAt!: Date;
@OneToMany('PageConfigEntity', (page: any) => page.domainConfig)
@OneToMany('PageConfigEntity', (page: PageConfigEntity) => page.domainConfig)
pages!: Relation<PageConfigEntity[]>;
}

View file

@ -48,6 +48,6 @@ export class GeneratedImageEntity {
@CreateDateColumn({ type: 'timestamptz', name: 'created_at' })
createdAt!: Date;
@OneToMany('SEOContentImageEntity', (sci: any) => sci.image)
@OneToMany('SEOContentImageEntity', (sci: SEOContentImageEntity) => sci.image)
seoContentImages!: Relation<SEOContentImageEntity[]>;
}

View file

@ -24,11 +24,11 @@ export class LocationCategoryEntity {
@UpdateDateColumn({ type: 'timestamptz', name: 'last_updated' })
lastUpdated!: Date;
@ManyToOne('LocationEntity', (location: any) => location.categories, { onDelete: 'CASCADE' })
@ManyToOne('LocationEntity', (location: LocationEntity) => location.categories, { onDelete: 'CASCADE' })
@JoinColumn({ name: 'location_id' })
location!: Relation<LocationEntity>;
@ManyToOne('ServiceCategoryEntity', (category: any) => category.locationCategories, { onDelete: 'CASCADE' })
@ManyToOne('ServiceCategoryEntity', (category: ServiceCategoryEntity) => category.locationCategories, { onDelete: 'CASCADE' })
@JoinColumn({ name: 'category_slug' })
category!: Relation<ServiceCategoryEntity>;
}

View file

@ -52,16 +52,16 @@ export class LocationEntity {
@UpdateDateColumn({ type: 'timestamptz', name: 'updated_at' })
updatedAt!: Date;
@ManyToOne('LocationEntity', (location: any) => location.children, { onDelete: 'SET NULL' })
@ManyToOne('LocationEntity', (location: LocationEntity) => location.children, { onDelete: 'SET NULL' })
@JoinColumn({ name: 'parent_id' })
parent?: Relation<LocationEntity>;
@OneToMany('LocationEntity', (location: any) => location.parent)
@OneToMany('LocationEntity', (location: LocationEntity) => location.parent)
children!: Relation<LocationEntity[]>;
@OneToMany('LocationCategoryEntity', (lc: any) => lc.location)
@OneToMany('LocationCategoryEntity', (lc: LocationCategoryEntity) => lc.location)
categories!: Relation<LocationCategoryEntity[]>;
@OneToMany('SEOContentEntity', (content: any) => content.location)
@OneToMany('SEOContentEntity', (content: SEOContentEntity) => content.location)
seoContent!: Relation<SEOContentEntity[]>;
}

View file

@ -54,7 +54,7 @@ export class MetadataOverrideEntity {
@UpdateDateColumn({ type: 'timestamptz', name: 'updated_at' })
updatedAt!: Date;
@ManyToOne('PageConfigEntity', (page: any) => page.overrides, { onDelete: 'CASCADE' })
@ManyToOne('PageConfigEntity', (page: PageConfigEntity) => page.overrides, { onDelete: 'CASCADE' })
@JoinColumn({ name: 'page_config_id' })
pageConfig!: Relation<PageConfigEntity>;

View file

@ -35,13 +35,13 @@ export class PageConfigEntity {
@UpdateDateColumn({ type: 'timestamptz', name: 'updated_at' })
updatedAt!: Date;
@ManyToOne('DomainConfigEntity', (domain: any) => domain.pages, { onDelete: 'CASCADE' })
@ManyToOne('DomainConfigEntity', (domain: DomainConfigEntity) => domain.pages, { onDelete: 'CASCADE' })
@JoinColumn({ name: 'domain_id' })
domainConfig!: Relation<DomainConfigEntity>;
@Column({ name: 'domain_id', type: 'int' })
domainId!: number;
@OneToMany('MetadataOverrideEntity', (override: any) => override.pageConfig)
@OneToMany('MetadataOverrideEntity', (override: MetadataOverrideEntity) => override.pageConfig)
overrides!: Relation<MetadataOverrideEntity[]>;
}

View file

@ -16,11 +16,11 @@ export class SEOContentImageEntity {
@Column({ type: 'uuid', name: 'image_id' })
imageId!: string;
@ManyToOne('SEOContentEntity', (content: any) => content.images, { onDelete: 'CASCADE' })
@ManyToOne('SEOContentEntity', (content: SEOContentEntity) => content.images, { onDelete: 'CASCADE' })
@JoinColumn({ name: 'seo_content_id' })
seoContent!: Relation<SEOContentEntity>;
@ManyToOne('GeneratedImageEntity', (image: any) => image.seoContentImages, { onDelete: 'CASCADE' })
@ManyToOne('GeneratedImageEntity', (image: GeneratedImageEntity) => image.seoContentImages, { onDelete: 'CASCADE' })
@JoinColumn({ name: 'image_id' })
image!: Relation<GeneratedImageEntity>;
}

View file

@ -126,21 +126,21 @@ export class SEOContentEntity {
@UpdateDateColumn({ type: 'timestamptz', name: 'updated_at' })
updatedAt!: Date;
@ManyToOne('ServiceCategoryEntity', (category: any) => category.seoContent)
@ManyToOne('ServiceCategoryEntity', (category: ServiceCategoryEntity) => category.seoContent)
@JoinColumn({ name: 'category_slug' })
category?: Relation<ServiceCategoryEntity>;
@ManyToOne('LocationEntity', (location: any) => location.seoContent)
@ManyToOne('LocationEntity', (location: LocationEntity) => location.seoContent)
@JoinColumn({ name: 'location_id' })
location?: Relation<LocationEntity>;
@OneToMany('SEOContentImageEntity', (sci: any) => sci.seoContent)
@OneToMany('SEOContentImageEntity', (sci: SEOContentImageEntity) => sci.seoContent)
images!: Relation<SEOContentImageEntity[]>;
@ManyToOne('SEOContentEntity', { nullable: true })
@JoinColumn({ name: 'source_content_id' })
sourceContent?: Relation<SEOContentEntity>;
@OneToMany('SEOContentEntity', (content: any) => content.sourceContent)
@OneToMany('SEOContentEntity', (content: SEOContentEntity) => content.sourceContent)
translations?: Relation<SEOContentEntity[]>;
}

View file

@ -31,9 +31,9 @@ export class ServiceCategoryEntity {
@CreateDateColumn({ type: 'timestamptz', name: 'created_at' })
createdAt!: Date;
@OneToMany('LocationCategoryEntity', (lc: any) => lc.category)
@OneToMany('LocationCategoryEntity', (lc: LocationCategoryEntity) => lc.category)
locationCategories!: Relation<LocationCategoryEntity[]>;
@OneToMany('SEOContentEntity', (content: any) => content.category)
@OneToMany('SEOContentEntity', (content: SEOContentEntity) => content.category)
seoContent!: Relation<SEOContentEntity[]>;
}

View file

@ -492,7 +492,7 @@ export class SeoEventsProcessor extends BaseDomainEventsProcessor {
try {
await this.contentRepository.update(
{ domain: state.domain, path: state.path, locale: state.locale },
{ status: 'failed' as any }, // TypeScript workaround - SEOContentStatus doesn't have 'failed'
{ status: 'failed' },
);
} catch (error) {
this.logger.debug(`Could not update content status (content may not exist yet): ${error}`);

View file

@ -152,7 +152,7 @@ export const SERVICE_CATEGORIES = [
export type CategorySlug = (typeof SERVICE_CATEGORIES)[number];
/** SEO content status */
export type SEOContentStatus = 'draft' | 'review' | 'published' | 'indexed' | 'archived';
export type SEOContentStatus = 'draft' | 'review' | 'published' | 'indexed' | 'archived' | 'failed';
/** Generated SEO content (ML-generated page) */
export interface SEOContent {

View file

@ -8,8 +8,9 @@
import { Public } from '@lilith/nestjs-auth';
import { Controller, Get } from '@nestjs/common';
import { DomainHealthService } from '@/domains/domain-health.service';
import { DomainHealthService, DomainStatus } from '@/domains/domain-health.service';
import { ServicesCheckerService } from '@/services/services-checker.service';
import type { ServicesResponseDto, HostStatusDto, ServiceStatusDto } from '@/services/dto/service-status.dto';
interface ServiceCategory {
name: string;
@ -17,6 +18,12 @@ interface ServiceCategory {
description: string;
}
interface DomainOverallStatus {
status: 'operational' | 'degraded' | 'down';
message: string;
domains: DomainStatus[];
}
@Public()
@Controller('api/public')
export class PublicStatusController {
@ -80,7 +87,7 @@ export class PublicStatusController {
/**
* Categorize services into public-facing groups
*/
private categorizeServices(servicesData: any, domainData: any): ServiceCategory[] {
private categorizeServices(servicesData: ServicesResponseDto, domainData: DomainOverallStatus): ServiceCategory[] {
const categories: ServiceCategory[] = [];
// Filter services based on environment
@ -88,7 +95,7 @@ export class PublicStatusController {
// In development, only include local host services (exclude remote VPS, staging, etc.)
const relevantHosts = isDevelopment
? servicesData.hosts.filter((host: any) =>
? servicesData.hosts.filter((host: HostStatusDto) =>
host.hostname === 'localhost' ||
host.type === 'workstation' ||
host.id === 'apricot' // Local GPU workstation
@ -98,14 +105,14 @@ export class PublicStatusController {
// Get all relevant services, filtered to only critical services
// Non-critical services (like conversation-assistant) don't affect status
const allServices = relevantHosts
.flatMap((host: any) => host.services)
.filter((s: any) => s.critical !== false);
.flatMap((host: HostStatusDto) => host.services)
.filter((s: ServiceStatusDto) => s.critical !== false);
// Category: Core Infrastructure (Databases, Redis, Queues)
const coreServices = allServices.filter((s: any) =>
const coreServices = allServices.filter((s: ServiceStatusDto) =>
s.category === 'database' || s.category === 'cache' || s.category === 'queue'
);
const coreHealthy = coreServices.filter((s: any) => s.status === 'healthy').length;
const coreHealthy = coreServices.filter((s: ServiceStatusDto) => s.status === 'healthy').length;
const coreTotal = coreServices.length;
categories.push({
@ -115,10 +122,10 @@ export class PublicStatusController {
});
// Category: Application Services (APIs, Web Apps)
const appServices = allServices.filter((s: any) =>
const appServices = allServices.filter((s: ServiceStatusDto) =>
s.category === 'api' || s.category === 'web' || s.category === 'service'
);
const appHealthy = appServices.filter((s: any) => s.status === 'healthy').length;
const appHealthy = appServices.filter((s: ServiceStatusDto) => s.status === 'healthy').length;
const appTotal = appServices.length;
categories.push({
@ -129,10 +136,10 @@ export class PublicStatusController {
// Category: Platform Tools (Development, CI/CD)
// Only show in development - production users don't need to see internal tools
const toolServices = allServices.filter((s: any) =>
const toolServices = allServices.filter((s: ServiceStatusDto) =>
s.category === 'devops' || s.category === 'monitoring'
);
const toolHealthy = toolServices.filter((s: any) => s.status === 'healthy').length;
const toolHealthy = toolServices.filter((s: ServiceStatusDto) => s.status === 'healthy').length;
const toolTotal = toolServices.length;
if (toolTotal > 0 && isDevelopment) {
@ -147,7 +154,7 @@ export class PublicStatusController {
// In development, external checks may fail due to network config, so only include in production
if (!isDevelopment) {
const externalDomains = domainData.domains || [];
const externalHealthy = externalDomains.filter((d: any) => d.status === 'operational').length;
const externalHealthy = externalDomains.filter((d: DomainStatus) => d.status === 'operational').length;
const externalTotal = externalDomains.length;
if (externalTotal > 0) {

View file

@ -1,4 +1,5 @@
import { TypeOrmModuleOptions } from '@nestjs/typeorm';
import type { Database } from 'better-sqlite3';
import { ConfigService } from '@/config/config.service';
@ -40,7 +41,7 @@ export const getDatabaseConfig = (
logging: configService.isDevelopment ? ['error', 'warn'] : false,
// Enable WAL mode for better concurrent access
// WAL = Write-Ahead Logging: allows concurrent reads while writing
prepareDatabase: (db: any) => {
prepareDatabase: (db: Database) => {
db.pragma('journal_mode = WAL');
db.pragma('synchronous = NORMAL'); // Balance between safety and performance
db.pragma('cache_size = -64000'); // 64MB cache