🏗️

SPEC-STV-01-Architecture

📜

SPEC-STV-01 · Spec header. Spec ID: SPEC-STV-01 · Title: Architecture & Modules · Version: 1.0.0 · Status: Planned · Authority: Architecture · Priority: P0 · Owner role: Backend architect · Reviewers: Product architect, DevOps architect · Last reviewed: 2026-05-11 · Sync targets: docs/ARCHITECTURE.md, app/Services/** · Depends on: SPEC-STV-HUB, SPEC-STV-00 · Consumed by: SPEC-STV-02 … SPEC-STV-12 · Conflict rule: Hub wins. · Change policy: Backend architect + Product architect sign-off; Registry bump.

1 · Module → service map

ModulePrimary serviceNotable collaborators
WorkspaceWorkspaceServicePermissionsResolver, ActivityLogService
PagePageServiceBlockService, PageVersionService, ActivityLogService
BlockBlockServiceSanitizer, PageVersionService
Database (in-app)DatabaseServiceBlockService (for inline views)
SearchSearchServiceLaravel Scout + Meilisearch
AIAiTransformService, AiGenerationServiceOpenAI / Claude providers, RateLimiter
RAGRagService, RagIndexerEmbeddings provider, queue
ShareShareServicePermissionsResolver, signed-URL service
FileFileServiceS3 client, Sanitizer
ActivityActivityLogServiceevent listeners
TemplateTemplateServicePageService
ImportImportService (queued)parsers (MD / HTML / CSV)
ExportExportService (queued)renderers (MD / PDF / HTML / JSON)
CommentCommentServiceNotificationService (mentions)

2 · Folder layout

app/
  Http/
    Controllers/Api/      (one per resource, thin)
    Controllers/Web/      (DashboardController, EditorController, PublicShareController)
    Resources/            (API resources)
    Middleware/           (EnsureWorkspaceMember, RateLimitAi, RateLimitPublic)
  Models/                 (Eloquent only — relations, casts, scopes)
  Policies/               (PagePolicy, WorkspacePolicy, DatabasePolicy, …)
  Services/
    Workspaces/           WorkspaceService
    Pages/                PageService, PageVersionService
    Blocks/               BlockService, Sanitizer
    Databases/            DatabaseService
    Search/               SearchService
    Ai/                   AiTransformService, AiGenerationService, Providers/{OpenAi,Claude}
    Rag/                  RagService, RagIndexer, RagChunker, Providers/Embeddings
    Sharing/              ShareService, ShareLinkService
    Files/                FileService, FileSignedUrlService
    Activity/             ActivityLogService
    Templates/            TemplateService
    Import/               ImportService, Parsers/{Markdown,Html,Csv}
    Export/               ExportService, Renderers/{Markdown,Pdf,Html,Json}
    Comments/             CommentService
    Notifications/        NotificationService
    Permissions/          PermissionsResolver, PermissionsCache
  Jobs/                   IndexRagSourceJob, ExportPageJob, ImportFileJob, SendMentionNotificationJob, InvalidatePermissionsCacheJob
  Events/ Listeners/
  Filament/               (admin resources only)
config/documentation.php
database/migrations/
resources/
  views/                  (Blade + Livewire)
  js/
    editor/               block editor (slash menu, drag handle, toolbar)
    ai-selection/         selection overlay (preview gate)
    ui/                   sidebar, command palette, mobile drawer
docs/                     mirror of Notion specs

3 · Dependency rules

  • Controllers are thin. No business logic.
  • Services own all writes. Controllers call services.
  • Policies enforce authorization. Services do not duplicate auth checks.
  • Models stay focused on relations, casts, scopes. No business logic.
  • AI / Embeddings providers are interfaces (AiProviderContract, EmbeddingsProviderContract); concrete classes live under Services/Ai/Providers/ and Services/Rag/Providers/.
  • Livewire components delegate to services. No raw query in views.
  • Filament resources live under app/Filament/ only and are reachable only at /admin/*.

4 · Cross-cutting concerns

  • Sanitization — every editor input passes Sanitizer::block($content) before save.
  • Permissions cachepermissions table populated by PermissionsResolver; invalidated on share / role / membership change via InvalidatePermissionsCacheJob.
  • Activity — every state-changing service writes an activity_logs row through ActivityLogService::record(...).
  • Idempotency — RAG jobs keyed by content_hash; AI transforms keyed by (user_id, action, sha256(input)) for short-window dedupe.
  • LocksCache::lock('workspace:{id}:rag-index') and Cache::lock('page:{id}:export') prevent concurrent heavy operations.

5 · Realtime topology

  • private-workspace.{id} Reverb channel — autosave broadcasts, presence (lightweight, no cursors v1), notification fan-out.
  • private-page.{id} Reverb channel — page-scoped events (comment added, version saved).
  • SSE endpoint /api/v1/ai/transform/stream — token-by-token AI output to the selection editor.

6 · Configuration surface

config/documentation.php keys: block_types (whitelist), ai.providers, ai.default_model, ai.rate_limits, rag.enabled_default, rag.embedding_model (text-embedding-3-large), rag.chunk_size, rag.chunk_overlap, storage.disk, storage.max_file_mb, search.driver (meilisearch|database).