feat(m15): full test completion + quality gate + validation fixes
- Add E2E notifications.spec (member-added notification -> list -> mark read) and activity-log.spec (board_posted + todo_created recorded) - Set Playwright workers=1 for deterministic full-suite runs (SSE test under parallel load); full E2E suite (18 tests / 13 specs incl. 12 mandated scenarios) green - Quality gate: 251 unit/integration tests, lint clean, typecheck clean, build succeeds, coverage 91.13% Repository/Service (>=80%) - Validation fixes (mandatory): SearchService now searches ALL items (large pageSize) instead of first page only; MeetingService. checkScheduleConflicts now requires membership (actorId) to prevent non-member info enumeration
This commit is contained in:
@ -31,6 +31,9 @@ export interface SearchOptions {
|
||||
type?: SearchResourceType;
|
||||
}
|
||||
|
||||
// 検索は全件対象とする(ページネーション既定値による検索漏れを防ぐ)
|
||||
const SEARCH_MAX = Number.MAX_SAFE_INTEGER;
|
||||
|
||||
/**
|
||||
* プロジェクト内の横断検索を担うService。
|
||||
* 各リソースを取得しキーワードで絞り込む(小規模データ前提)。
|
||||
@ -62,7 +65,10 @@ export class SearchService {
|
||||
!!text && text.toLowerCase().includes(q);
|
||||
|
||||
if (!type || type === 'thread') {
|
||||
for (const t of this.boardRepository.findThreads(projectId).items) {
|
||||
for (const t of this.boardRepository.findThreads(projectId, {
|
||||
page: 1,
|
||||
pageSize: SEARCH_MAX,
|
||||
}).items) {
|
||||
if (match(t.title) || match(t.bodyMd)) {
|
||||
results.push({
|
||||
type: 'thread',
|
||||
@ -74,7 +80,10 @@ export class SearchService {
|
||||
}
|
||||
}
|
||||
if (!type || type === 'chat') {
|
||||
for (const m of this.chatRepository.findMessages(projectId).items) {
|
||||
for (const m of this.chatRepository.findMessages(projectId, {
|
||||
page: 1,
|
||||
pageSize: SEARCH_MAX,
|
||||
}).items) {
|
||||
if (match(m.body)) {
|
||||
results.push({
|
||||
type: 'chat',
|
||||
@ -101,7 +110,7 @@ export class SearchService {
|
||||
const files = this.fileRepository.findFilesByProject(
|
||||
projectId,
|
||||
1,
|
||||
500
|
||||
SEARCH_MAX
|
||||
).items;
|
||||
for (const f of files) {
|
||||
if (match(f.originalName)) {
|
||||
@ -156,7 +165,10 @@ export class SearchService {
|
||||
}
|
||||
}
|
||||
if (!type || type === 'note') {
|
||||
for (const n of this.noteRepository.findNotes(projectId).items) {
|
||||
for (const n of this.noteRepository.findNotes(projectId, {
|
||||
page: 1,
|
||||
pageSize: SEARCH_MAX,
|
||||
}).items) {
|
||||
if (match(n.title) || match(n.bodyMd) || match(n.tags)) {
|
||||
results.push({
|
||||
type: 'note',
|
||||
|
||||
Reference in New Issue
Block a user