Architecture Guide - striae-org/striae GitHub Wiki

Table of Contents

  1. System Architecture Overview
  2. High-Level Architecture
  3. Frontend Architecture
  4. Backend Architecture (Cloudflare Workers)
  5. Data Architecture
  6. Security Architecture
  7. Performance Architecture
  8. Scalability Considerations
  9. Monitoring and Observability
  10. Development Architecture
  11. Future Architecture Considerations
  12. References

System Architecture Overview

Striae is an edge-first forensic annotation platform with clear separation between:

  • Presentation and workflow orchestration in the React Router app.
  • Same-origin API gateway behavior in Cloudflare Pages Functions (/api/*).
  • Domain services in specialized Cloudflare Workers.
  • Storage systems partitioned by data responsibility.

The architecture emphasizes service boundaries, typed contracts, and forensic workflow integrity across export, import, and audit paths.

High-Level Architecture

graph TB
    subgraph "Client and App"
        UI[React Router App on Cloudflare Pages]
        AUTH[Firebase Authentication]
    end

    subgraph "Pages API Gateway"
        API[Cloudflare Pages Functions /api/*]
    end

    subgraph "Edge Service Layer"
        UW[User Worker]
        DW[Data Worker]
        AW[Audit Worker]
        IW[Image Worker]
        PW[PDF Worker]
    end

    subgraph "Storage Layer"
        KV[Cloudflare KV]
        R2D[Cloudflare R2 - Case Data]
        R2A[Cloudflare R2 - Audit Data]
        R2F[Cloudflare R2 - Encrypted Files]
    end

    AUTH --> UI
    UI --> API

    API --> UW
    API --> DW
    API --> AW
    API --> IW
    API --> PW

    UW --> KV
    DW --> R2D
    AW --> R2A
    IW --> R2F

Architecture Patterns

  • Bounded edge services: each worker owns a focused domain boundary.
  • Gateway-first transport: browser clients call same-origin Pages APIs, which verify Firebase identity and forward to workers via Cloudflare Service Bindings.
  • Storage by concern: user identity/profile, case content, and audit evidence are separated.
  • Fail-safe observability: audit logging is integrated broadly but does not generally block core user workflows.
  • Typed data contracts: shared application types define domain boundaries across frontend and services.

Frontend Architecture

Technology Stack

  • Framework: React Router (React)
  • Language: TypeScript
  • Styling: CSS Modules and shared global styles
  • Deployment Runtime: Cloudflare Pages

Key Frontend Patterns

1. Route-driven shell

  • Routes provide page-level composition and navigation state.
  • Domain UI is composed from feature-focused components rather than monolithic pages.

2. Canvas-centered casework flow

  • Annotation and casework interactions are centered around the canvas domain.
  • Sidebar and toolbar state act as control surfaces around the same case context.

3. Action/service boundary

  • UI interactions delegate data and workflow operations to action modules and utility services.
  • This keeps worker communication and business logic out of presentational components.
  • Utility clients call same-origin /api/* routes instead of direct worker domains.

4. Workflow pipelines

  • Export, import, confirmation, and audit workflows are organized as explicit multi-step flows.
  • Long-running operations expose progress and error states to maintain user trust and recoverability.
  • Case archival is implemented as a dedicated workflow that produces signed archive packages with bundled audit artifacts.

5. Shared domain typing

  • Shared types in app/types define stable contracts across components and services.
  • The app uses centralized utility modules for permissions, data access, and audit operations.
  • Derived confirmation-status summaries are maintained as typed metadata to accelerate file/case confirmation indicators without rescanning all annotations.

For component-level structure and implementation details, use Component Guide.

Backend Architecture (Cloudflare Workers)

Worker Services Overview

Striae uses domain-focused workers to isolate responsibilities and simplify scaling:

Worker Primary Domain Architecture Role
User Worker User profile and case assignment state Identity-linked profile boundary
Data Worker Case, file metadata, and signing operations Primary case data boundary
Audit Worker Audit entry persistence and retrieval Immutable accountability boundary
Image Worker Encrypted file/image upload, read, and deletion Media/file boundary
PDF Worker Report rendering and PDF generation Document generation boundary

Current worker implementations are modularized inside each workers/*/src/ tree rather than concentrated in single entrypoint files. Shared patterns now include dedicated handlers/, storage/, registry/, cleanup/, and formats/ modules where they fit the domain.

Worker Boundaries

User Worker (workers/user-worker/)

  • Owns user profile lifecycle and case assignment state as the identity-linked boundary.
  • Stores user profile records in USER_DB as encryption envelopes (RSA-OAEP wrapped AES-256-GCM payloads) and decrypts only inside trusted worker paths.
  • Implements modular architecture:
    • Entry point (src/user-worker.ts): handles authentication, KV config validation, and request routing.
    • Auth (src/auth.ts): Firebase token verification and KV permission requirements.
    • Handlers (src/handlers/user-routes.ts): unified endpoint router for user profile and case operations (GET, PUT, DELETE).
    • Storage (src/storage/): KV access, encryption envelope serialization, and user data persistence.
    • Registry (src/registry/): data-at-rest encryption key lookup and active key management.
    • Cleanup (src/cleanup/): cascading deletion logic for account termination and case removal.
    • Firebase (src/firebase/): Firebase Admin SDK integration for user context from bearer tokens.
    • Crypto utilities (src/encryption-utils.ts): RSA-OAEP key wrapping and AES-256-GCM envelope encryption/decryption.
    • Config (src/config.ts): auth header names, KV namespace names, and path constants.
    • Types (src/types.ts): user profile, case, and API contract types.
  • Enforces read/write KV permissions separately to allow fine-grained deployment scope.
  • Supports case assignment tracking and user account lifecycle including secure deletion.

Image Worker (workers/image-worker/)

  • Owns encrypted file and image blob storage in a dedicated R2 bucket.
  • Implements modular handler architecture for focused separation of concerns:
    • Entry point (src/image-worker.ts): handles error boundaries and delegates to router.
    • Router (src/router.ts): dispatches requests by HTTP method and path segments to appropriate handler modules.
    • Handlers (src/handlers/): specialized modules for focused operations:
      • upload-image.ts: multipart upload and encryption with envelope storage in R2 metadata.
      • serve-image.ts: authenticated read with decryption from R2 metadata envelopes.
      • delete-image.ts: secure deletion with cleanup.
      • mint-signed-url.ts: HMAC-signed same-origin URL generation.
    • Security layer (src/security/):
      • key-registry.ts: active encryption key lookup and management.
      • signed-url.ts: HMAC generation and validation for delegated browser access.
    • Encryption utilities (src/encryption-utils.ts): AES-256-GCM encryption/decryption with envelope pattern.
    • Utils (src/utils/): path parsing, content-disposition headers, storage metadata extraction.
    • Auth (src/auth.ts): JWT verification for image worker requests.
    • Types (src/types.ts): request, response, and configuration contracts.
  • Encrypts uploads at rest and decrypts on authenticated reads.
  • Mints and validates signed same-origin image URLs so browser image surfaces can load media through /api/image/{fileId}?st=... without exposing worker secrets to the client.
  • Supports encrypted media with data-at-rest envelope storage in R2 custom metadata and per-request decryption.

PDF Worker (workers/pdf-worker/)

  • Isolates report rendering and PDF generation from application UI concerns.
  • Implements modular report format architecture:
    • Entry point (src/pdf-worker.ts): handles auth headers and request routing.
    • Report types (src/report-types.ts): shared TypeScript interfaces for report generation contracts and PDF options.
    • Report layout (src/report-layout.ts): shared rendering utilities and layout logic across formats.
    • Audit report renderer (src/audit-trail-report.ts): comprehensive case audit trail PDF rendering (including raw JSON appendix sections) used when data.reportMode = "audit-trail".
    • Format modules (src/formats/): format-specific rendering implementations loaded dynamically:
      • format-striae.ts: default forensic annotation report format.
      • format-primer-shear.ts: agency-specific report variant.
    • Assets (src/assets/): images, templates, and resources used by report formats.
  • Uses Cloudflare Browser Rendering API with scoped bearer auth for HTML-to-PDF conversion.
  • Does not persist report payloads; rendering input is processed in-memory per request.
  • Supports format discovery and extension through modular loader pattern.
  • Supports case-audit report mode for viewer-driven audit trail exports without adding a separate PDF worker endpoint.

Data Worker (workers/data-worker/)

  • Owns case and annotation JSON persistence model.
  • Implements modular handler and storage architecture:
    • Entry point (src/data-worker.ts): handles auth header validation and request routing to handlers.
    • Handlers (src/handlers/):
      • storage-routes.ts: case/annotation CRUD operations and R2 lifecycle.
      • signing.ts: forensic manifest, confirmation, and audit export signing endpoints.
      • decrypt-export.ts: decryption service for encrypted export payloads with verification.
    • Registry (src/registry/): data-at-rest encryption key lookup and rotation management.
    • Crypto utilities:
      • encryption-utils.ts: AES-256-GCM encryption/decryption with envelope envelopes.
      • signature-utils.ts: RSA-PSS signing for manifest integrity.
      • signing-payload-utils.ts: payload preparation for cryptographic operations.
    • Config (src/config.ts): auth header names, path constants, and environment bindings.
    • Types (src/types.ts): request, response, and storage contracts.
  • Provides signing and decryption services for forensic manifest, confirmation, audit export, and encrypted package workflows.
  • Maintains separation between case storage operations and cryptographic signing services.

Audit Worker (workers/audit-worker/)

  • Owns append-oriented audit storage and retrieval as immutable evidence records.
  • Implements modular architecture:
    • Entry point (src/audit-worker.ts): handles auth header validation, request routing, and path validation.
    • Handlers (src/handlers/audit-routes.ts): unified audit endpoint router for GET/POST operations.
    • Storage (src/storage/): R2 bucket access, encryption envelope management, and append-only log semantics.
    • Crypto (src/crypto/): AES-256-GCM encryption/decryption and signing utilities for audit records.
    • Config (src/config.ts): auth header validation, path constants, and environment bindings.
    • Types (src/types.ts): audit entry, query, and response contracts.
  • Preserves forensic accountability as a distinct data concern separate from operational case storage.
  • Supports paginated retrieval and filtering while maintaining immutable audit trail integrity.

For endpoint-level contracts and request/response formats, use API Reference.

Data Architecture

Storage Systems Overview

Data Category Primary Store Architectural Purpose
User profile and permissions Cloudflare KV Fast key-value profile lookup by user identity with worker-managed encryption-at-rest envelopes
Case and annotation payloads Cloudflare R2 (data bucket) Encrypted-at-rest casework artifacts
Audit evidence trail Cloudflare R2 (audit bucket) Encrypted-at-rest accountability records
File and image binaries Cloudflare R2 (files bucket) Encrypted-at-rest media/file storage with decrypt-on-read
Authentication identity Firebase Auth Externalized identity and auth lifecycle

For encryption implementation details, key registry patterns, and key rotation behavior, see Data-at-Rest Encryption.

Data Ownership Model

  • User domain: profile metadata and case references.
  • Case domain: examination content and associated annotation artifacts.
  • Audit domain: immutable event evidence retained separately from case content.
  • Media domain: file and image binaries managed independently from case metadata with at-rest encryption.

Derived Workflow Metadata

  • A per-user confirmation status summary document is stored at /{userId}/meta/confirmation-status.json.
  • The summary tracks per-file and per-case includeConfirmation/isConfirmed state and is refreshed opportunistically with staleness checks.
  • Destructive lifecycle operations (case deletion, case archival, account deletion) remove affected summary entries to prevent stale UI status data.

This ownership model is designed to reduce coupling, support forensic traceability, and allow domain-specific scaling.

For concrete schemas and payload contracts, use API Reference.

Security Architecture

Striae security is implemented as layered boundaries rather than a single control point:

  • Identity boundary: Firebase-authenticated user sessions.
  • Gateway boundary: Pages Functions validate Firebase bearer tokens and enforce user-scope rules before forwarding.
  • Service boundary: workers are called exclusively via Cloudflare Service Bindings from Pages Functions, eliminating the need for internal shared-secret auth headers across the proxy boundary; the Image Worker additionally enforces HMAC-signed st tokens for delegated browser image reads.
  • Data boundary: separation of operational case data and audit evidence stores.
  • Cryptography boundary: user profile KV, case/audit payloads, and file/image payloads are encrypted at rest and decrypted only in trusted worker paths.
  • Integrity boundary: signed forensic payloads for export/import trust workflows.

For detailed security controls, authentication flows, and hardening guidance, use:

Performance Architecture

Performance relies on edge-local compute and clear workload specialization:

  • Stateless worker execution for low-latency API handling.
  • Separation of hot-path interactions (annotation and casework) from heavier jobs (export and PDF).
  • Storage and media services selected by workload profile (KV, R2, Browser Rendering API).
  • Browser-side UX patterns that keep long-running operations observable and recoverable.

Scalability Considerations

  • Independent service scaling: workers scale per workload domain.
  • Storage elasticity: object and key-value stores scale independently of compute.
  • Domain isolation: case, audit, file/image, and identity concerns can evolve without full-stack rewrites.
  • Extensible report and export pipelines: architecture supports format/module growth without core redesign.

Monitoring and Observability

Observability is layered across platform, application, and forensic accountability domains:

  • Platform-level worker/runtime metrics and error visibility.
  • Application-level structured logging and error propagation.
  • Audit-level event trails for workflow accountability and compliance review.

For audit-specific observability and reporting workflows, use Audit Trail System.

Development Architecture

The development model favors clear boundaries and centralized shared contracts:

  • Feature-oriented frontend modules with reusable utility and service layers.
  • Public API transport through Pages Functions (/api/user, /api/data, /api/image, /api/audit, /api/pdf).
  • Worker services organized by domain ownership with modular internal source layouts.
  • Pages Functions route to workers via Cloudflare Service Bindings (env.USER_WORKER, env.DATA_WORKER, etc.) rather than HTTP domain proxying.
  • Centralized type definitions to keep contracts stable across features.
  • Documentation split by responsibility to avoid architecture-guide overload.

For implementation workflow and operations process, use:

Future Architecture Considerations

Likely extension points while preserving current architecture patterns:

  • Additional report modules and agency-specific output formats.
  • Policy-driven authorization layers over existing permission boundaries.
  • Expanded analytics and compliance reporting pipelines from audit events.
  • Greater workflow modularity for specialized forensic review paths.

References