# jaynik-s/sentimentscribe architecture

> Architecture diagram of the GitHub repository jaynik-s/sentimentscribe, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-29). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/jaynik-s/sentimentscribe
- Repository: https://github.com/jaynik-s/sentimentscribe

## Overview

SentimentScribe is a privacy-first journaling application. Users authenticate, unlock the diary locally, write encrypted entries, and save them online or offline; optional analysis and recommendations send chosen text to the backend. The graph follows the documented client/API workflow and sampled controller/service ownership. Feature wiring not present in the sampled source is included only where the README documents it; some backend use-case and frontend page details remain unsampled.

Main entry points: [`frontend/src/pages`](https://github.com/jaynik-s/sentimentscribe/tree/main/frontend/src/pages) (App pages), [`frontend/src/api/entries.ts`](https://github.com/jaynik-s/sentimentscribe/blob/main/frontend/src/api/entries.ts) (Entry API), [`frontend/src/api/analysis.ts`](https://github.com/jaynik-s/sentimentscribe/blob/main/frontend/src/api/analysis.ts) (Analysis API), [`frontend/src/api/recommendations.ts`](https://github.com/jaynik-s/sentimentscribe/blob/main/frontend/src/api/recommendations.ts) (Recommendations API)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_client["Browser application"]
  node_pages["App pages"]
  node_routes["Routes and guards<br/>[routes.tsx]"]
  node_authstate["Auth state<br/>[auth.tsx]"]
  node_http["API client<br/>[http.ts]"]
  node_entryapi["Entry API<br/>[entries.ts]"]
  node_analysisapi["Analysis API<br/>[analysis.ts]"]
  node_recommendapi["Recommendations API<br/>[recommendations.ts]"]
end

subgraph group_privacy["Encryption and offline"]
  node_crypto["Entry encryption"]
  node_offline[("Local entry cache<br/>[entriesRepo.ts]")]
  node_sync["Offline sync engine<br/>[syncEngine.ts]"]
  node_queue["Sync queue<br/>[syncQueueRepo.ts]"]
end

subgraph group_api["Backend API"]
  node_authcontroller["Auth endpoints"]
  node_authservice["Authentication service<br/>[AuthService.java]"]
  node_jwt["JWT service<br/>[JwtService.java]"]
  node_userstore[("User records")]
  node_entriescontroller["Entry endpoints"]
  node_entryservice["Entry service<br/>[EntryService.java]"]
  node_entryrepo["Entry persistence adapter"]
  node_analysiscontroller["Analysis endpoint"]
  node_recommendcontroller["Recommendation endpoint"]
  node_recommendservice["Recommendation service"]
end

subgraph group_domain["Journal and insights"]
  node_entryusecases["Entry use cases"]
  node_analysis["Keyword analysis"]
  node_recommendusecase["Recommendation use case"]
end

subgraph group_integrations["External services"]
  node_nlp["NLP analysis access"]
  node_spotify["Spotify access"]
  node_tmdb["TMDb access"]
end

node_user(("Journal user"))
node_postgres[("PostgreSQL")]
node_spotifyservice{{"Spotify API"}}
node_tmdbservice{{"TMDb API"}}

node_user -->|"uses"| node_pages
node_pages -->|"navigates"| node_routes
node_routes -->|"checks access"| node_authstate
node_pages -->|"encrypts locally"| node_crypto
node_pages -->|"caches ciphertext"| node_offline
node_pages -->|"requests entries"| node_entryapi
node_entryapi -->|"sends requests"| node_http
node_pages -->|"requests analysis"| node_analysisapi
node_analysisapi -->|"sends requests"| node_http
node_pages -->|"requests suggestions"| node_recommendapi
node_recommendapi -->|"sends requests"| node_http
node_offline -->|"queues changes"| node_queue
node_sync -->|"reads and updates"| node_queue
node_sync -->|"replays changes"| node_entryapi
node_user -->|"registers or logs in"| node_authcontroller
node_authcontroller -->|"delegates"| node_authservice
node_authservice -->|"reads and writes"| node_userstore
node_authservice -->|"issues token"| node_jwt
node_entryapi -->|"calls entry API"| node_entriescontroller
node_entriescontroller -->|"delegates"| node_entryservice
node_entryservice -->|"executes"| node_entryusecases
node_entryusecases -->|"accesses entries"| node_entryrepo
node_entryrepo -->|"reads and writes ciphertext"| node_postgres
node_analysisapi -->|"calls analysis API"| node_analysiscontroller
node_analysiscontroller -->|"delegates"| node_analysis
node_analysis -->|"extracts keywords"| node_nlp
node_recommendapi -->|"calls recommendations API"| node_recommendcontroller
node_recommendcontroller -->|"delegates"| node_recommendservice
node_recommendservice -->|"executes"| node_recommendusecase
node_recommendusecase -->|"requests songs"| node_spotify
node_recommendusecase -->|"requests movies"| node_tmdb
node_spotify -->|"queries"| node_spotifyservice
node_tmdb -->|"queries"| node_tmdbservice

click node_pages "https://github.com/jaynik-s/sentimentscribe/tree/main/frontend/src/pages"
click node_routes "https://github.com/jaynik-s/sentimentscribe/blob/main/frontend/src/routes.tsx"
click node_authstate "https://github.com/jaynik-s/sentimentscribe/blob/main/frontend/src/state/auth.tsx"
click node_http "https://github.com/jaynik-s/sentimentscribe/blob/main/frontend/src/api/http.ts"
click node_entryapi "https://github.com/jaynik-s/sentimentscribe/blob/main/frontend/src/api/entries.ts"
click node_analysisapi "https://github.com/jaynik-s/sentimentscribe/blob/main/frontend/src/api/analysis.ts"
click node_recommendapi "https://github.com/jaynik-s/sentimentscribe/blob/main/frontend/src/api/recommendations.ts"
click node_crypto "https://github.com/jaynik-s/sentimentscribe/tree/main/frontend/src/crypto"
click node_offline "https://github.com/jaynik-s/sentimentscribe/blob/main/frontend/src/offline/entriesRepo.ts"
click node_sync "https://github.com/jaynik-s/sentimentscribe/blob/main/frontend/src/offline/syncEngine.ts"
click node_queue "https://github.com/jaynik-s/sentimentscribe/blob/main/frontend/src/offline/syncQueueRepo.ts"
click node_authcontroller "https://github.com/jaynik-s/sentimentscribe/blob/main/backend/src/main/java/com/sentimentscribe/web/AuthController.java"
click node_authservice "https://github.com/jaynik-s/sentimentscribe/blob/main/backend/src/main/java/com/sentimentscribe/service/AuthService.java"
click node_jwt "https://github.com/jaynik-s/sentimentscribe/blob/main/backend/src/main/java/com/sentimentscribe/service/JwtService.java"
click node_userstore "https://github.com/jaynik-s/sentimentscribe/blob/main/backend/src/main/java/com/sentimentscribe/persistence/postgres/repo/UserJpaRepository.java"
click node_entriescontroller "https://github.com/jaynik-s/sentimentscribe/blob/main/backend/src/main/java/com/sentimentscribe/web/EntriesController.java"
click node_entryservice "https://github.com/jaynik-s/sentimentscribe/blob/main/backend/src/main/java/com/sentimentscribe/service/EntryService.java"
click node_entryusecases "https://github.com/jaynik-s/sentimentscribe/tree/main/backend/src/main/java/com/sentimentscribe/usecase"
click node_entryrepo "https://github.com/jaynik-s/sentimentscribe/blob/main/backend/src/main/java/com/sentimentscribe/persistence/postgres/PostgresDiaryEntryRepositoryAdapter.java"
click node_analysiscontroller "https://github.com/jaynik-s/sentimentscribe/blob/main/backend/src/main/java/com/sentimentscribe/web/AnalysisController.java"
click node_analysis "https://github.com/jaynik-s/sentimentscribe/tree/main/backend/src/main/java/com/sentimentscribe/usecase/analyze_keywords"
click node_nlp "https://github.com/jaynik-s/sentimentscribe/blob/main/backend/src/main/java/com/sentimentscribe/data/NLPAnalysisDataAccessObject.java"
click node_recommendcontroller "https://github.com/jaynik-s/sentimentscribe/blob/main/backend/src/main/java/com/sentimentscribe/web/RecommendationsController.java"
click node_recommendservice "https://github.com/jaynik-s/sentimentscribe/blob/main/backend/src/main/java/com/sentimentscribe/service/RecommendationService.java"
click node_recommendusecase "https://github.com/jaynik-s/sentimentscribe/tree/main/backend/src/main/java/com/sentimentscribe/usecase/get_recommendations"
click node_spotify "https://github.com/jaynik-s/sentimentscribe/blob/main/backend/src/main/java/com/sentimentscribe/data/SpotifyAPIAccessObject.java"
click node_tmdb "https://github.com/jaynik-s/sentimentscribe/blob/main/backend/src/main/java/com/sentimentscribe/data/TMDbAPIAccessObject.java"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_pages,node_routes,node_authstate,node_http,node_entryapi,node_analysisapi,node_recommendapi,node_user toneBlue
class node_crypto,node_offline,node_sync,node_queue,node_postgres toneAmber
class node_authcontroller,node_authservice,node_jwt,node_userstore,node_entriescontroller,node_entryservice,node_entryrepo,node_analysiscontroller,node_recommendcontroller,node_recommendservice,node_spotifyservice,node_tmdbservice toneMint
class node_entryusecases,node_analysis,node_recommendusecase toneRose
class node_nlp,node_spotify,node_tmdb toneIndigo
```

## Components

### Browser application

- [App pages](https://github.com/jaynik-s/sentimentscribe/tree/main/frontend/src/pages): `frontend/src/pages`
- [Routes and guards](https://github.com/jaynik-s/sentimentscribe/blob/main/frontend/src/routes.tsx): `frontend/src/routes.tsx`
- [Auth state](https://github.com/jaynik-s/sentimentscribe/blob/main/frontend/src/state/auth.tsx): `frontend/src/state/auth.tsx`
- [API client](https://github.com/jaynik-s/sentimentscribe/blob/main/frontend/src/api/http.ts): `frontend/src/api/http.ts`
- [Entry API](https://github.com/jaynik-s/sentimentscribe/blob/main/frontend/src/api/entries.ts): `frontend/src/api/entries.ts`
- [Analysis API](https://github.com/jaynik-s/sentimentscribe/blob/main/frontend/src/api/analysis.ts): `frontend/src/api/analysis.ts`
- [Recommendations API](https://github.com/jaynik-s/sentimentscribe/blob/main/frontend/src/api/recommendations.ts): `frontend/src/api/recommendations.ts`

### Encryption and offline

- [Entry encryption](https://github.com/jaynik-s/sentimentscribe/tree/main/frontend/src/crypto): `frontend/src/crypto`
- [Local entry cache](https://github.com/jaynik-s/sentimentscribe/blob/main/frontend/src/offline/entriesRepo.ts): `frontend/src/offline/entriesRepo.ts`
- [Offline sync engine](https://github.com/jaynik-s/sentimentscribe/blob/main/frontend/src/offline/syncEngine.ts): `frontend/src/offline/syncEngine.ts`
- [Sync queue](https://github.com/jaynik-s/sentimentscribe/blob/main/frontend/src/offline/syncQueueRepo.ts): `frontend/src/offline/syncQueueRepo.ts`

### Backend API

- [Auth endpoints](https://github.com/jaynik-s/sentimentscribe/blob/main/backend/src/main/java/com/sentimentscribe/web/AuthController.java): `backend/src/main/java/com/sentimentscribe/web/AuthController.java`
- [Authentication service](https://github.com/jaynik-s/sentimentscribe/blob/main/backend/src/main/java/com/sentimentscribe/service/AuthService.java): `backend/src/main/java/com/sentimentscribe/service/AuthService.java`
- [JWT service](https://github.com/jaynik-s/sentimentscribe/blob/main/backend/src/main/java/com/sentimentscribe/service/JwtService.java): `backend/src/main/java/com/sentimentscribe/service/JwtService.java`
- [User records](https://github.com/jaynik-s/sentimentscribe/blob/main/backend/src/main/java/com/sentimentscribe/persistence/postgres/repo/UserJpaRepository.java): `backend/src/main/java/com/sentimentscribe/persistence/postgres/repo/UserJpaRepository.java`
- [Entry endpoints](https://github.com/jaynik-s/sentimentscribe/blob/main/backend/src/main/java/com/sentimentscribe/web/EntriesController.java): `backend/src/main/java/com/sentimentscribe/web/EntriesController.java`
- [Entry service](https://github.com/jaynik-s/sentimentscribe/blob/main/backend/src/main/java/com/sentimentscribe/service/EntryService.java): `backend/src/main/java/com/sentimentscribe/service/EntryService.java`
- [Entry persistence adapter](https://github.com/jaynik-s/sentimentscribe/blob/main/backend/src/main/java/com/sentimentscribe/persistence/postgres/PostgresDiaryEntryRepositoryAdapter.java): `backend/src/main/java/com/sentimentscribe/persistence/postgres/PostgresDiaryEntryRepositoryAdapter.java`
- [Analysis endpoint](https://github.com/jaynik-s/sentimentscribe/blob/main/backend/src/main/java/com/sentimentscribe/web/AnalysisController.java): `backend/src/main/java/com/sentimentscribe/web/AnalysisController.java`
- [Recommendation endpoint](https://github.com/jaynik-s/sentimentscribe/blob/main/backend/src/main/java/com/sentimentscribe/web/RecommendationsController.java): `backend/src/main/java/com/sentimentscribe/web/RecommendationsController.java`
- [Recommendation service](https://github.com/jaynik-s/sentimentscribe/blob/main/backend/src/main/java/com/sentimentscribe/service/RecommendationService.java): `backend/src/main/java/com/sentimentscribe/service/RecommendationService.java`

### Journal and insights

- [Entry use cases](https://github.com/jaynik-s/sentimentscribe/tree/main/backend/src/main/java/com/sentimentscribe/usecase): `backend/src/main/java/com/sentimentscribe/usecase`
- [Keyword analysis](https://github.com/jaynik-s/sentimentscribe/tree/main/backend/src/main/java/com/sentimentscribe/usecase/analyze_keywords): `backend/src/main/java/com/sentimentscribe/usecase/analyze_keywords`
- [Recommendation use case](https://github.com/jaynik-s/sentimentscribe/tree/main/backend/src/main/java/com/sentimentscribe/usecase/get_recommendations): `backend/src/main/java/com/sentimentscribe/usecase/get_recommendations`

### External services

- [NLP analysis access](https://github.com/jaynik-s/sentimentscribe/blob/main/backend/src/main/java/com/sentimentscribe/data/NLPAnalysisDataAccessObject.java): `backend/src/main/java/com/sentimentscribe/data/NLPAnalysisDataAccessObject.java`
- [Spotify access](https://github.com/jaynik-s/sentimentscribe/blob/main/backend/src/main/java/com/sentimentscribe/data/SpotifyAPIAccessObject.java): `backend/src/main/java/com/sentimentscribe/data/SpotifyAPIAccessObject.java`
- [TMDb access](https://github.com/jaynik-s/sentimentscribe/blob/main/backend/src/main/java/com/sentimentscribe/data/TMDbAPIAccessObject.java): `backend/src/main/java/com/sentimentscribe/data/TMDbAPIAccessObject.java`

### Other components

- **Journal user**
- **PostgreSQL**
- **Spotify API**
- **TMDb API**

## Connections

- Journal user → App pages: uses
- App pages → Routes and guards: navigates
- Routes and guards → Auth state: checks access
- App pages → Entry encryption: encrypts locally
- App pages → Local entry cache: caches ciphertext
- App pages → Entry API: requests entries
- Entry API → API client: sends requests
- App pages → Analysis API: requests analysis
- Analysis API → API client: sends requests
- App pages → Recommendations API: requests suggestions
- Recommendations API → API client: sends requests
- Local entry cache → Sync queue: queues changes
- Offline sync engine → Sync queue: reads and updates
- Offline sync engine → Entry API: replays changes
- Journal user → Auth endpoints: registers or logs in
- Auth endpoints → Authentication service: delegates
- Authentication service → User records: reads and writes
- Authentication service → JWT service: issues token
- Entry API → Entry endpoints: calls entry API
- Entry endpoints → Entry service: delegates
- Entry service → Entry use cases: executes
- Entry use cases → Entry persistence adapter: accesses entries
- Entry persistence adapter → PostgreSQL: reads and writes ciphertext
- Analysis API → Analysis endpoint: calls analysis API
- Analysis endpoint → Keyword analysis: delegates
- Keyword analysis → NLP analysis access: extracts keywords
- Recommendations API → Recommendation endpoint: calls recommendations API
- Recommendation endpoint → Recommendation service: delegates
- Recommendation service → Recommendation use case: executes
- Recommendation use case → Spotify access: requests songs
- Recommendation use case → TMDb access: requests movies
- Spotify access → Spotify API: queries
- TMDb access → TMDb API: queries
