# tdenkov123/garchive architecture

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

- Interactive diagram: https://gitdiagram.com/tdenkov123/garchive
- Repository: https://github.com/tdenkov123/garchive

## Overview

#### Purpose and Entry Point
GArchive is a Go gRPC service for file metadata and upload lifecycle management. File bytes are stored in S3-compatible MinIO; PostgreSQL holds metadata and multipart state; Redis accelerates reads; Kafka receives domain events. The process starts at `cmd/server/main.go`, which composes dependencies through `internal/app/app.go`.

#### Public API Contract
The gRPC contract defines single-upload, multipart-upload, read/list, download URL, and delete operations. Generated server/client bindings are under `api/gen/file/v1/file_grpc.pb.go`; the source-of-truth schema is `api/proto/file/v1/file.proto`. Request handling enters through `internal/grpc/handler.go`.

#### Application and Service Layer
`internal/service/file_service.go` implements file lifecycle operations: create metadata, issue presigned upload/download URLs, confirm checksums, read/list records, and soft-delete files. `internal/service/multipart_service.go` owns multipart state transitions, part URL issuance/reporting, completion, and abort. `internal/service/adapters.go` defines the boundary-facing dependencies consumed by services, keeping business workflows independent of concrete infrastructure.

#### Request Control Plane
gRPC middleware applies cross-cutting controls before handlers: JWT identity extraction/authentication, rate limiting, validation, logging/metrics/error handling. Relevant paths are `internal/grpc/middleware/interceptors.go`, `internal/grpc/middleware/ratelimit.go`, and `internal/auth/jwt.go`. Authenticated ownership and request context are propagated through `internal/auth/context.go`; audit records are emitted via `internal/audit/audit.go`.

#### Persistence, Cache, and Object Storage
PostgreSQL is the authoritative metadata store, with schema migrations for files and multipart uploads in `internal/repository/postgres/migrations/001_init.sql` and `internal/repository/postgres/migrations/002_multipart.sql`. Repository implementations live in `internal/repository/postgres/file.go`. Redis caching is isolated behind `internal/cache/redis/cache.go`. MinIO access, including presigned URL and object lifecycle operations, is encapsulated in `internal/storage/minio/client.go`.

#### Events and Lifecycle Flow
For a single upload, the service persists a pending file record, returns a presigned PUT URL, then validates a supplied SHA-256 checksum during confirmation before marking the record ready. Multipart uploads persist upload/part progress until completion or abort. Ready and deletion lifecycle changes publish Kafka domain events through `internal/service/events.go` and `internal/events/kafka/publisher.go`. Object operations cross the MinIO boundary; metadata transitions cross PostgreSQL; cache invalidation/population accompanies read/write paths.

#### Runtime and Deployment Boundaries
The service runs as a containerized Go process (`Dockerfile`) and exposes gRPC on port 50051, Prometheus metrics on 9090, and gRPC health. Local orchestration is defined in `docker-compose.yml`; production composition is in `docker-compose.prod.yml`. Core external runtime services are PostgreSQL, Redis, MinIO, and Kafka; optional profiles add Keycloak for OIDC demonstration and Jaeger observability. TLS server credentials are handled by `internal/tlsutil/credentials.go`, while configuration is centralized in `internal/config/config.go`.

Main entry points: [`internal/service/adapters.go`](https://github.com/tdenkov123/garchive/blob/master/internal/service/adapters.go) (Service dependency ports), [`internal/grpc/middleware/interceptors.go`](https://github.com/tdenkov123/garchive/blob/master/internal/grpc/middleware/interceptors.go) (Request interceptors), [`internal/grpc/handler.go`](https://github.com/tdenkov123/garchive/blob/master/internal/grpc/handler.go) (File RPC handler), [`internal/service/file_service.go`](https://github.com/tdenkov123/garchive/blob/master/internal/service/file_service.go) (File lifecycle service)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_runtime["Runtime"]
  node_container["Go service container<br/>runtime"]
  node_composition["Dependency composition<br/>bootstrap<br/>[app.go]"]
end

subgraph group_grpc["gRPC edge"]
  node_grpc_contract["File gRPC contract<br/>protobuf API<br/>[file.proto]"]
  node_grpc_bindings["Generated gRPC bindings<br/>generated API<br/>[file_grpc.pb.go]"]
  node_interceptors["Request interceptors<br/>gRPC middleware<br/>[interceptors.go]"]
  node_rate_limit["Rate limiting<br/>middleware control<br/>[ratelimit.go]"]
  node_grpc_handler["File RPC handler<br/>gRPC handler<br/>[handler.go]"]
  node_jwt_auth["JWT identity<br/>authentication<br/>[jwt.go]"]
end

subgraph group_application["Application"]
  node_file_service["File lifecycle service<br/>application service<br/>[file_service.go]"]
  node_multipart_service["Multipart lifecycle service<br/>application service"]
  node_service_adapters{{"Service dependency ports<br/>application ports<br/>[adapters.go]"}}
  node_lifecycle_events["Lifecycle event publisher<br/>domain events<br/>[events.go]"]
end

subgraph group_infrastructure["Infrastructure"]
  node_postgres_repo[("PostgreSQL repository<br/>metadata repository<br/>[file.go]")]
  node_redis_cache["Redis cache<br/>cache adapter<br/>[cache.go]"]
  node_minio_client["MinIO storage client<br/>object storage adapter<br/>[client.go]"]
  node_kafka_publisher["Kafka publisher<br/>event adapter<br/>[publisher.go]"]
end

subgraph group_external["External services"]
  node_postgres[("PostgreSQL<br/>external database<br/>[001_init.sql]")]
  node_redis[("Redis<br/>external cache")]
  node_minio[("MinIO<br/>external object storage")]
  node_kafka["Kafka<br/>external event bus"]
end

node_container -->|"starts"| node_composition
node_composition -->|"configures"| node_interceptors
node_grpc_contract -->|"generates"| node_grpc_bindings
node_grpc_bindings -->|"server interface"| node_grpc_handler
node_interceptors -->|"enforces"| node_rate_limit
node_interceptors -->|"authenticates"| node_jwt_auth
node_interceptors -->|"wraps"| node_grpc_handler
node_grpc_handler -->|"single-file RPCs"| node_file_service
node_grpc_handler -->|"multipart RPCs"| node_multipart_service
node_file_service -->|"uses ports"| node_service_adapters
node_multipart_service -->|"uses ports"| node_service_adapters
node_file_service -->|"ready/delete"| node_lifecycle_events
node_multipart_service -->|"completion"| node_lifecycle_events
node_service_adapters -->|"metadata state"| node_postgres_repo
node_service_adapters -->|"cache reads/writes"| node_redis_cache
node_service_adapters -->|"presigned/object operations"| node_minio_client
node_lifecycle_events -->|"publishes"| node_kafka_publisher
node_postgres_repo -->|"persists"| node_postgres
node_redis_cache -->|"caches"| node_redis
node_minio_client -->|"stores objects"| node_minio
node_kafka_publisher -->|"emits events"| node_kafka

click node_container "https://github.com/tdenkov123/garchive/blob/master/Dockerfile"
click node_composition "https://github.com/tdenkov123/garchive/blob/master/internal/app/app.go"
click node_grpc_contract "https://github.com/tdenkov123/garchive/blob/master/api/proto/file/v1/file.proto"
click node_grpc_bindings "https://github.com/tdenkov123/garchive/blob/master/api/gen/file/v1/file_grpc.pb.go"
click node_interceptors "https://github.com/tdenkov123/garchive/blob/master/internal/grpc/middleware/interceptors.go"
click node_rate_limit "https://github.com/tdenkov123/garchive/blob/master/internal/grpc/middleware/ratelimit.go"
click node_grpc_handler "https://github.com/tdenkov123/garchive/blob/master/internal/grpc/handler.go"
click node_jwt_auth "https://github.com/tdenkov123/garchive/blob/master/internal/auth/jwt.go"
click node_file_service "https://github.com/tdenkov123/garchive/blob/master/internal/service/file_service.go"
click node_multipart_service "https://github.com/tdenkov123/garchive/blob/master/internal/service/multipart_service.go"
click node_service_adapters "https://github.com/tdenkov123/garchive/blob/master/internal/service/adapters.go"
click node_lifecycle_events "https://github.com/tdenkov123/garchive/blob/master/internal/service/events.go"
click node_postgres_repo "https://github.com/tdenkov123/garchive/blob/master/internal/repository/postgres/file.go"
click node_redis_cache "https://github.com/tdenkov123/garchive/blob/master/internal/cache/redis/cache.go"
click node_minio_client "https://github.com/tdenkov123/garchive/blob/master/internal/storage/minio/client.go"
click node_kafka_publisher "https://github.com/tdenkov123/garchive/blob/master/internal/events/kafka/publisher.go"
click node_postgres "https://github.com/tdenkov123/garchive/blob/master/internal/repository/postgres/migrations/001_init.sql"

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_container,node_composition toneBlue
class node_grpc_contract,node_grpc_bindings,node_interceptors,node_rate_limit,node_grpc_handler,node_jwt_auth toneAmber
class node_file_service,node_multipart_service,node_service_adapters,node_lifecycle_events toneMint
class node_postgres_repo,node_redis_cache,node_minio_client,node_kafka_publisher toneRose
class node_postgres,node_redis,node_minio,node_kafka toneIndigo
```

## Components

### Runtime

- [Go service container](https://github.com/tdenkov123/garchive/blob/master/Dockerfile): runtime · Exposes gRPC, health, and Prometheus endpoints. · `Dockerfile`
- [Dependency composition](https://github.com/tdenkov123/garchive/blob/master/internal/app/app.go): bootstrap · `internal/app/app.go`

### gRPC edge

- [File gRPC contract](https://github.com/tdenkov123/garchive/blob/master/api/proto/file/v1/file.proto): protobuf API · Defines upload, multipart, read, URL, and delete RPCs. · `api/proto/file/v1/file.proto`
- [Generated gRPC bindings](https://github.com/tdenkov123/garchive/blob/master/api/gen/file/v1/file_grpc.pb.go): generated API · `api/gen/file/v1/file_grpc.pb.go`
- [Request interceptors](https://github.com/tdenkov123/garchive/blob/master/internal/grpc/middleware/interceptors.go): gRPC middleware · Applies auth, validation, rate limits, logging, metrics, and errors. · `internal/grpc/middleware/interceptors.go`
- [Rate limiting](https://github.com/tdenkov123/garchive/blob/master/internal/grpc/middleware/ratelimit.go): middleware control · `internal/grpc/middleware/ratelimit.go`
- [File RPC handler](https://github.com/tdenkov123/garchive/blob/master/internal/grpc/handler.go): gRPC handler · `internal/grpc/handler.go`
- [JWT identity](https://github.com/tdenkov123/garchive/blob/master/internal/auth/jwt.go): authentication · Propagates authenticated ownership through request context. · `internal/auth/jwt.go`

### Application

- [File lifecycle service](https://github.com/tdenkov123/garchive/blob/master/internal/service/file_service.go): application service · Manages single-upload metadata, URLs, checksums, reads, and deletion. · `internal/service/file_service.go`
- [Multipart lifecycle service](https://github.com/tdenkov123/garchive/blob/master/internal/service/multipart_service.go): application service · Manages upload state, parts, completion, and abort. · `internal/service/multipart_service.go`
- [Service dependency ports](https://github.com/tdenkov123/garchive/blob/master/internal/service/adapters.go): application ports · Keeps lifecycle workflows independent of infrastructure. · `internal/service/adapters.go`
- [Lifecycle event publisher](https://github.com/tdenkov123/garchive/blob/master/internal/service/events.go): domain events · Publishes ready and deletion changes. · `internal/service/events.go`

### Infrastructure

- [PostgreSQL repository](https://github.com/tdenkov123/garchive/blob/master/internal/repository/postgres/file.go): metadata repository · Authoritative files and multipart state. · `internal/repository/postgres/file.go`
- [Redis cache](https://github.com/tdenkov123/garchive/blob/master/internal/cache/redis/cache.go): cache adapter · Caches read paths and supports invalidation. · `internal/cache/redis/cache.go`
- [MinIO storage client](https://github.com/tdenkov123/garchive/blob/master/internal/storage/minio/client.go): object storage adapter · Issues presigned URLs and performs object lifecycle operations. · `internal/storage/minio/client.go`
- [Kafka publisher](https://github.com/tdenkov123/garchive/blob/master/internal/events/kafka/publisher.go): event adapter · `internal/events/kafka/publisher.go`

### External services

- [PostgreSQL](https://github.com/tdenkov123/garchive/blob/master/internal/repository/postgres/migrations/001_init.sql): external database · Schema includes file and multipart records. · `internal/repository/postgres/migrations/001_init.sql`
- **Redis**: external cache
- **MinIO**: external object storage · Stores file bytes.
- **Kafka**: external event bus

## Connections

- Go service container → Dependency composition: starts
- Dependency composition → Request interceptors: configures
- File gRPC contract → Generated gRPC bindings: generates
- Generated gRPC bindings → File RPC handler: server interface
- Request interceptors → Rate limiting: enforces
- Request interceptors → JWT identity: authenticates
- Request interceptors → File RPC handler: wraps
- File RPC handler → File lifecycle service: single-file RPCs
- File RPC handler → Multipart lifecycle service: multipart RPCs
- File lifecycle service → Service dependency ports: uses ports
- Multipart lifecycle service → Service dependency ports: uses ports
- File lifecycle service → Lifecycle event publisher: ready/delete
- Multipart lifecycle service → Lifecycle event publisher: completion
- Service dependency ports → PostgreSQL repository: metadata state
- Service dependency ports → Redis cache: cache reads/writes
- Service dependency ports → MinIO storage client: presigned/object operations
- Lifecycle event publisher → Kafka publisher: publishes
- PostgreSQL repository → PostgreSQL: persists
- Redis cache → Redis: caches
- MinIO storage client → MinIO: stores objects
- Kafka publisher → Kafka: emits events
