feat(beta): public spaces

This commit is contained in:
Philipinho
2026-09-05 11:25:50 +01:00
parent 5b85464561
commit a12bf42078
117 changed files with 7593 additions and 716 deletions
@@ -12,6 +12,7 @@ import {
import { SearchService } from './search.service';
import {
SearchDTO,
SearchPublicSpaceDTO,
SearchShareDTO,
SearchSuggestionDTO,
} from './dto/search.dto';
@@ -28,6 +29,8 @@ import { AuthUser } from '../../common/decorators/auth-user.decorator';
import { Public } from 'src/common/decorators/public.decorator';
import { EnvironmentService } from '../../integrations/environment/environment.service';
import { ModuleRef } from '@nestjs/core';
import { PublicSpaceService } from '../public-space/public-space.service';
import { PageRepo } from '@docmost/db/repos/page/page.repo';
@UseGuards(JwtAuthGuard)
@Controller('search')
@@ -38,6 +41,8 @@ export class SearchController {
private readonly searchService: SearchService,
private readonly spaceAbility: SpaceAbilityFactory,
private readonly environmentService: EnvironmentService,
private readonly publicSpaceService: PublicSpaceService,
private readonly pageRepo: PageRepo,
private moduleRef: ModuleRef,
) {}
@@ -109,14 +114,51 @@ export class SearchController {
});
}
@Public()
@HttpCode(HttpStatus.OK)
@Post('public-space-search')
async searchPublicSpace(
@Body() searchDto: SearchPublicSpaceDTO,
@AuthWorkspace() workspace: Workspace,
) {
delete searchDto.spaceId;
delete searchDto.shareId;
// Member-facing filters stay internal: creator identities and label
// taxonomy must not become a grouping oracle on the anonymous surface.
delete searchDto.creatorId;
delete searchDto.labelIds;
const { space } = await this.publicSpaceService.getPublicSpace(
searchDto.spaceSlug,
workspace,
);
const pages = await this.pageRepo.getSpacePagesExcludingRestricted(
space.id,
);
const publicPageIds = pages.map((page) => page.id);
if (this.environmentService.getSearchDriver() === 'typesense') {
return this.searchTypesense(searchDto, {
workspaceId: workspace.id,
publicPageIds,
});
}
return this.searchService.searchPage(searchDto, {
workspaceId: workspace.id,
publicPageIds,
});
}
async searchTypesense(
searchParams: SearchDTO,
opts: {
userId?: string;
workspaceId: string;
publicPageIds?: string[];
},
) {
const { userId, workspaceId } = opts;
const { userId, workspaceId, publicPageIds } = opts;
let TypesenseModule: any;
try {
// eslint-disable-next-line @typescript-eslint/no-require-imports
@@ -132,6 +174,7 @@ export class SearchController {
return PageSearchService.searchPage(searchParams, {
userId: userId,
workspaceId,
publicPageIds,
});
} catch (err) {
this.logger.debug(