Neuer Block-Atom task_overview (Markdown-Fence dorfteich-tasks, HTML-Placeholder). Shared extractTaskRows liest Task-Zeilen mit Text, Mentions (#150) und Start-/Zieldaten (#152); TasksService sammelt zur Lesezeit den Teilbaum (rekursiv via collectSubtreeIds, canAccessPage- Filter je Quellseite) aus Basis-State + page_updates-Log — KEINE abgeleitete Tabelle nötig (Teilbäume sind klein, kein Drift). Neuer auth-Endpoint GET /read/:pond/:slug/tasks; die öffentliche Ansicht expandiert den Placeholder serverseitig zur statischen Tabelle (Instanz-Sprache). NodeView mit Live-Tabelle und Rückschreib-Checkboxen (optimistisch, Override bis der debounced Collab-Persist nachzieht); Einfügen über die Block-Auswahl (eingebauter Eintrag). Unit- + DB-Tests, neuer CI-Pack tasks.spec (voller Loop inkl. Rückschreiben end-to-end), User-Guide-Doku en+de. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0155v2aT8AG1kZDQEZiCLBWC
49 lines
2.0 KiB
TypeScript
49 lines
2.0 KiB
TypeScript
import { Controller, Get, Param, Req } from '@nestjs/common';
|
|
import type { TaskOverviewPage } from '@dorfteich/shared';
|
|
|
|
import { AuthedRequest } from '../auth/auth.guard';
|
|
import { TasksService } from '../pages/tasks.service';
|
|
import { AuthenticatedOnly } from '../permissions/permission.decorators';
|
|
import { PublicPageContent, PublicService } from './public.service';
|
|
|
|
/**
|
|
* Authenticated read-rendering (issue #135). Returns a page's rendered read
|
|
* HTML — plugin fallbacks, expanded page embeds, resolved media — for a
|
|
* signed-in viewer with read access. The transclusion node view fetches this to
|
|
* show an embedded page's content inline in the authenticated read view, which
|
|
* must also work for pages that are not public and so are out of reach of the
|
|
* `/public` endpoints. NOT `@Public`: the auth guard requires a session and the
|
|
* service enforces read permission (a non-readable page 404s, no leak).
|
|
*/
|
|
@Controller('read')
|
|
export class ReadContentController {
|
|
constructor(
|
|
private readonly publicPages: PublicService,
|
|
private readonly tasks: TasksService,
|
|
) {}
|
|
|
|
// The task collection (issue #154) — registered before the generic
|
|
// two-segment route so `tasks` is not read as a page slug.
|
|
@Get(':pondSlug/:pageSlug/tasks')
|
|
@AuthenticatedOnly()
|
|
async tasksOf(
|
|
@Param('pondSlug') pondSlug: string,
|
|
@Param('pageSlug') pageSlug: string,
|
|
@Req() request: AuthedRequest,
|
|
): Promise<TaskOverviewPage[]> {
|
|
return this.tasks.collect(request.user ?? null, pondSlug, pageSlug);
|
|
}
|
|
|
|
// Session required (explicit access rule, issue #52); per-page read
|
|
// permission is enforced in the service (resolve → canAccessPage → 404).
|
|
@Get(':pondSlug/:pageSlug')
|
|
@AuthenticatedOnly()
|
|
async content(
|
|
@Param('pondSlug') pondSlug: string,
|
|
@Param('pageSlug') pageSlug: string,
|
|
@Req() request: AuthedRequest,
|
|
): Promise<PublicPageContent> {
|
|
return this.publicPages.content(request.user ?? null, pondSlug, pageSlug);
|
|
}
|
|
}
|