Skip to main content

Codebase Flow Map

This page is for a new developer who needs to understand how Prismedia moves from screen to API to domain behavior to database and back again. It is a codebase map, not an exhaustive component catalog.

Read This First

Prismedia has three big rules that explain most of the repo:

  1. The .NET backend owns server behavior, persistence, HTTP contracts, migrations, jobs, playback preparation, and integration adapters.
  2. The Svelte app is a static frontend client. It calls the backend through generated OpenAPI clients and local presentation helpers.
  3. Long-running media work is durable job work. It moves through PostgreSQL job rows and the .NET worker, not a TypeScript worker or browser process.
  4. The native SwiftUI app is a separate client repository. It consumes the same canonical Entity routes and the same generated backend code manifest as Svelte.

Runtime Shape

The API process also applies EF Core migrations on startup. The worker waits for the database to be reachable and migrated before it begins claiming work.

Code Layout At A Glance

AreaPathWhat it owns
Web appapps/web-svelteSvelte routes, app chrome, stores, generated API client, entity grids/details, media players, readers.
API hostapps/backend/src/Prismedia.ApiMinimal API endpoint composition, auth, OpenAPI, static frontend hosting, codegen manifest, HTTP result mapping.
Contractsapps/backend/src/Prismedia.ContractsPublic .NET request/response DTOs consumed by OpenAPI generation.
Applicationapps/backend/src/Prismedia.ApplicationUse-case services, job handlers, ports, settings, security, and playback policy.
Domainapps/backend/src/Prismedia.DomainEntity kinds, behavior-bearing entities, capabilities, coded enums, taxonomy concepts.
Infrastructureapps/backend/src/Prismedia.InfrastructureEF Core, row models, migrations, repositories/read services, media tools, plugins, requests, queue storage.
Workerapps/backend/src/Prismedia.WorkerHosted process that registers worker services and runs queue/scheduler hosted services.
Shared UIpackages/ui-svelteDomain-free Svelte primitives, composed UI pieces, tokens, motion helpers.
Native appPrismedia-SwiftUI/PrismediaShared in the sibling native repositorySwift Entity transport models, feature services/state, shared SwiftUI Entity detail and thumbnail presentation.
Documentation sitedocumentation-siteDocusaurus docs published separately from the app shell.

Dependency Direction

The most important practical habit: when a feature touches a user action, start at the route or endpoint, then follow the dependency direction inward. Do not skip directly from a Svelte component into database-shaped assumptions.

Request To Render Flow

Read-only endpoints often project EF rows directly into contract DTOs. Writes should flow through a command or use-case service, call domain behavior where there is a business invariant, and save once per use case whenever possible.

Frontend Flow

The frontend is route-driven, but the reusable entity scaffolds carry a lot of the product surface:

  • EntityIndexPage owns the common library page shell.
  • EntityGrid, EntityGridToolbar, EntityGridFilterDrawer, and pagination modules own browsing, filtering, selection, and view modes.
  • EntityDetail owns the shared detail surface for descriptions, metadata, images, relationships, children, progress, and edit actions.
  • EntityThumbnail owns grid card rendering, artwork fallbacks, preview hover, badges, progress, and reference chips.
  • Route pages usually choose kind-specific configuration and delegate to shared scaffolds instead of rebuilding layouts from scratch.

The SwiftUI app follows the same Entity API root through PrismediaAPIClient, PrismediaEntityDetailLoader, feature-owned service/state, and shared native detail/thumbnail presentation. See Entity Definitions and Data Flow for the object-level backend, Svelte, and Swift diagrams.

API Surface Flow

Endpoint files should stay thin. They decode HTTP-shaped input, call application services, and return explicit contract DTOs or ApiProblem responses.

Important groups currently mapped:

GroupPrimary route areaTypical owner
Entity browse/detail/api/entities; kind aliases return the same documentIEntityReadService, EntityCardProjector, generated EntityCard.
Library roots/api/librariesSettings and scan-root persistence.
Files/api/filesFilesService, managed storage, file persistence.
Jobs/api/jobsJobService, IJobGraphService, IJobQueueService, durable graph/node/signal/resource rows.
Identify/api/identifyPlugin services, identify queues, cascade runners.
Requests/api/requestsPlugin discovery, proposal review, and wanted Entity creation.
Playback/api/playback, /api/music-playerPlayback planning and sessions, HLS assets, stream sources.
Settings/auth/api/settings, /api/auth, /api/usersSettings registry, user authentication, and user administration services.

Durable Job Flow

Registered handler families:

FamilyExamplesWhat they do
ScanningScanLibraryJobHandler, ScanGalleryJobHandler, ScanBookJobHandler, ScanAudioJobHandlerWalk roots, classify folders/files, upsert entities, enqueue downstream work.
ProbeProbeVideoJobHandler, ProbeAudioJobHandlerRun media probes and persist technical metadata.
FingerprintFingerprintJobHandler for video, image, audioCompute MD5/oshash-style fingerprints where enabled and needed.
Asset generationGrid thumbnails, image thumbnails, book covers/pages, audio waveforms, video previews, subtitlesProduce generated assets and capability state.
IdentifySearch, one-provider-per-Entity expansion, reviewed apply, auto identifyCall providers/plugins, wait durably for review, apply metadata, and append structural work in the same lane.
AcquisitionSearch, monitor, import, upgrade replace, finalizeWait for review/transfers, materialize exact Entities and files, reconcile readiness, and finalize usable imports.
MaintenanceRefresh entity, refresh collection, library maintenanceKeep derived views and stale records tidy.

Entity And Capability Flow

Conceptually, a definition describes a kind, a domain Entity carries one instance's behavior/state, EF rows persist it, and EntityCard projects one shared detail document. Mutable domain capabilities, immutable document capabilities, and application projector modules are different concerns. The focused Entity guide documents their construction, registration, persistence, and review rules in detail.

Generated Client And Code Constants

Any backend contract, OpenAPI operation, definition, or coded-enum change must be followed by regenerating the affected clients with the dev API running. pnpm api:check guards Svelte parity; the native repository's Scripts/check-contract-codes.py validates its generated manifest surfaces.

Main User Journey Maps

Browse To Playback

New Media Scan

Identify Review

Request Workflow

Where To Start For Common Changes

ChangeStart hereThen inspect
New library page or grid behaviorapps/web-svelte/src/lib/components/entities/EntityIndexPage.svelteEntityGrid.svelte, entity-grid.ts, route page for the kind.
Detail page layout or metadata editingEntityDetail.svelteentity-detail.ts, entity-detail-edit.ts, canonical Entity read, update endpoints.
New Entity kind or kind-wide policyConcrete Entity file and EntityKindDefinitionEntityKindRegistry, mapper only when detail state persists, code manifest, both generated clients.
New Entity capabilityDomain or document capability beside its ownerCapability mapper/projector, polymorphism discovery, generated clients and native decoder.
New API routePrismedia.Api/Endpoints/EndpointRouteBuilderExtensions.csMatching endpoint group, Prismedia.Contracts, generated client.
New backend settingAppSettingKeys.cs and AppSettingsRegistry.csSettings endpoints, generated codes, settings UI.
New closed-set codeDomain [Code] enum or constants manifestCodesManifest.cs, scripts/gen-codes.mjs, codes.ts.
New media scan behaviorScan handler for that familyLibraryScanPersistenceService.*, file classifier/parsing helpers, downstream job needs.
New worker jobPrismedia.Application/Jobs/DependencyInjection.csJobType, handler, queue tests, Jobs UI if surfaced.
Playback negotiation changeVideoPlaybackPlanService.csVideoDirectPlayPolicy, HlsAssetService*, /api/playback endpoints, VideoPlayer.svelte.
Plugin/identify behaviorIdentifyPluginService* or identify job handlersQueue store, proposal traversal, apply service, identify UI store.
Request integrationEndpoints/Requests/RequestEndpoints.cs and Endpoints/Acquisition/AcquisitionEndpoints.csPlugin discovery, acquisition use cases, indexer/download-client adapters, import and history tests.

Quality Snapshot

Strong Signals

  • The backend has an explicit architecture contract and a mechanical architecture audit script.
  • Domain, Application, Infrastructure, API, Worker, and Contracts are split into separate projects with mostly inward dependencies.
  • The Svelte client has a generated OpenAPI layer and a generated closed-code manifest layer.
  • The native client generates closed codes, complete Entity-kind definitions, and request definitions from that same backend manifest.
  • Tests exist across domain, infrastructure, API endpoints, frontend view-model helpers, Svelte components, and shared packages.
  • pnpm validate ties together version/changelog checks, generated-client drift, Svelte checks, unit tests, docs build, and backend tests.
  • Generated migrations and generated API files are isolated enough that large file size does not automatically imply hand-maintained complexity.

Architecture Audits

Do not preserve a dated analyzer result in this page. Run the current architecture tests and validation against the commit being reviewed, then inspect each result against the dependency rules above. Test-only references, generated contracts, and external adapter boundaries may need different treatment from production layer violations.

Hand-Maintained Hotspots

These files are not automatically bad; they are places where changes require careful reading, focused tests, and a preference for extracting proven patterns instead of adding one-off branches.

AreaHotspotWhy it matters
Frontend detail surfaceEntityDetail.svelteLarge shared page surface for many entity kinds. Small changes can affect movies, shows, books, images, audio, and taxonomy pages.
Frontend playbackVideoPlayer.svelteCoordinates browser media events, HLS, fallback, progress, controls, and recovery.
Frontend gridsEntityGrid.svelte, EntityGridToolbar.svelte, EntityThumbnail.svelteShared browsing behavior, filtering, selection, thumbnails, previews, and mobile ergonomics.
Identify UIidentify-store.svelte.ts, identify review componentsLong-running async state, provider selection, review/apply progress, and refresh survival.
API wrapperapps/web-svelte/src/lib/api/prismedia.tsTransitional wrapper around generated clients; useful but should not become a second contract layer.
Backend identifyIdentifyQueueService, IdentifyPluginService*Async matching, provider behavior, queue state, cascade and apply paths.
Backend playbackHlsAssetService*, playback policy servicesDirect play, direct stream, transcode, cache, seek, and process lifecycle all interact.
Backend scanningLibraryScanPersistenceService.*, scan handlersConverts files into canonical entities and downstream job work.
Backend queueJobGraphService, JobQueueService, QueueWorkerDependencies, durable waits, fair interactive/background lanes, CPU/provider/entity resources, visibility, retries, and cancellation.

Low-Noise Findings

  • TODO/FIXME comments are mostly inside vendored foliate-js reader code.
  • One application job handler logs that provider metadata import has not yet been migrated; that appears to be an explicit placeholder, not hidden dead code.
  • Generated files dominate the largest-file list only because EF migrations and generated API clients are necessarily verbose.

Release Readiness Checklist

Before a release branch or release image, run the checks from the repo root:

pnpm validate
dotnet build apps/backend/Prismedia.slnx
pnpm docs:check

When backend contracts or [Code] enums changed, run the app at http://localhost:8008, regenerate with:

pnpm --filter @prismedia/web-svelte api:generate
pnpm api:check

When runtime behavior changed, smoke the app through the .NET API at http://localhost:8008, not Vite directly.

Practical Mental Model

Use this path when you are lost:

Route or user action
-> shared frontend scaffold or page-local component
-> src/lib/api wrapper
-> generated OpenAPI operation
-> Prismedia.Api endpoint group
-> Application service, handler, or job handler
-> Domain behavior if a business rule is involved
-> Infrastructure EF/media/plugin adapter
-> PostgreSQL rows or generated assets
-> projected contract DTO
-> generated TypeScript model
-> screen state

If a proposed change skips a layer, ask why. Some read paths are intentionally projection-first for speed, and some compatibility paths have external route constraints, but those exceptions should be visible in code and tests.