{"id":40111650,"url":"https://github.com/dlcs/protagonist","last_synced_at":"2026-01-30T18:00:52.583Z","repository":{"id":37747293,"uuid":"233263698","full_name":"dlcs/protagonist","owner":"dlcs","description":null,"archived":false,"fork":false,"pushed_at":"2026-01-19T10:25:56.000Z","size":20677,"stargazers_count":7,"open_issues_count":133,"forks_count":2,"subscribers_count":8,"default_branch":"develop","last_synced_at":"2026-01-19T17:53:42.218Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dlcs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2020-01-11T16:44:16.000Z","updated_at":"2026-01-16T17:15:02.000Z","dependencies_parsed_at":"2025-12-03T02:04:31.195Z","dependency_job_id":null,"html_url":"https://github.com/dlcs/protagonist","commit_stats":null,"previous_names":[],"tags_count":52,"template":false,"template_full_name":null,"purl":"pkg:github/dlcs/protagonist","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dlcs%2Fprotagonist","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dlcs%2Fprotagonist/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dlcs%2Fprotagonist/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dlcs%2Fprotagonist/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dlcs","download_url":"https://codeload.github.com/dlcs/protagonist/tar.gz/refs/heads/develop","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dlcs%2Fprotagonist/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28917033,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-30T16:37:38.804Z","status":"ssl_error","status_checked_at":"2026-01-30T16:37:37.878Z","response_time":66,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-01-19T12:02:17.808Z","updated_at":"2026-01-30T18:00:52.577Z","avatar_url":"https://github.com/dlcs.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Protagonist\n\nA collection of separate dotnet core applications that together form the basis of the new DLCS platform.\n\n## About\n\n* [What is the DLCS?](docs/what-is-dlcs-io.md)\n* [Interaction Patterns](https://github.com/dlcs/protagonist/issues?q=is%3Aissue+label%3A%22Interaction+Pattern%22+sort%3Acreated-asc)\n* [Architectural Considerations](docs/architectural-considerations.md)\n* [Design Principles](docs/rfcs/006-Design-Principles.md)\n* [RFCs](docs/rfcs)\n* [Architecture Diagram](https://raw.githubusercontent.com/dlcs/protagonist/master/docs/c4-container-diagrams/DLCS-2023-l2.png)\n* [Public API Documentation](https://dlcs-book.readthedocs.io/en/latest/)\n\n## Projects\n\nThere are a number of shared projects and entry point applications that use these shared projects, detailed below:\n\n### Shared\n\n* DLCS.AWS - classes for interacting with AWS resources.\n* DLCS.Core - general non-domain specific utilities and exceptions.\n* DLCS.HydraModel - [Hydra](https://www.hydra-cg.com/) models for DLCS API.\n* DLCS.Mediatr - shared classes for projects using [Mediatr](https://github.com/jbogard/MediatR).\n* DLCS.Model - DLCS models and repository interfaces.\n* DLCS.Mock - Mock version of API serving pre-canned responses from memory.\n* DLCS.Repository - Repository implementations and `DbContext` for database.\n* DLCS.Web - Classes that are aware of HTTP pipeline (e.g. request/response classes)\n* Hydra - Base classes for Hydra objects (not DLCS specific).\n\nIn addition to the above there are a number of `*.Tests` classes for automated tests.\n\n### Entry Points\n\n* API - HTTP API for interactions.\n* Engine - asset ingestion/derivative creation.\n* Orchestrator - reverse proxy that serves user requests.\n* Portal - administration UI for managing assets.\n* Thumbs - simplified handling of thumbnail requests.\n* CleanupHandler - monitors queue for notifications + deletes asset derivatives on receipt.\n* Migrator - Applies any pending EF migrations.\n\n## Technology :robot:\n\nThere are a variety of technologies used across the projects, including:\n\n* [LazyCache](https://github.com/alastairtree/LazyCache) - lazy in-memory cache.\n* [Serilog](https://serilog.net/) - structured logging framework.\n* [Mediatr](https://github.com/jbogard/MediatR) - mediator implementation for in-proc messaging.\n* [EFCore](https://github.com/dotnet/efcore) - ORM data-access and migrations.\n* [Dapper](https://github.com/DapperLib/Dapper) - high performance object mapper.\n* [XUnit](https://xunit.net/) - automated test framework.\n\n## Deployment\n\n[Github actions](.github/workflows) are used to build and push new Docker images to github container registry.\n\nThe main entry point is [`run_build.yml`](.github/workflows/run_build.yml). This runs `dotnet test` then uses the parameterised `docker-build-and-push` files to handle Docker image creation.\n\nPRs to `main`, `develop`, pushes to `main`, `develop` and `v*` tags will:\n* Build + test dotnet code\n* Build and push docker containers \n  * This won't happen for draft PRs unless `build-image` label is added\n\nPushes to `main`, `develop` and `v*` tags will also run sonar analysis.\n\n## Configuration\n\nMultiple services use `ForwardedHeadersMiddleware` to listen for `X-Forwarded-Host` and `X-Forwarded-Proto`.\n\nBy default these only allow these headers to be set by requests from a `KnownNetwork` or `KnownHost` (see [`ForwardedHeaderMiddleware`](https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/proxy-load-balancer?view=aspnetcore-8.0#forwarded-headers-middleware-options) docs for more options).\n\nTo add to the default values, set `\"KnownNetwork\"` config setting, this should be set to a comma-delimited list of CIDR values.\n\nApplicable for `API`, `Thumbs` and `Orchestrator` services.\n\n## Getting Started\n\nThere are 2 docker-compose files:\n\n* `docker-compose.local.yml` - this will start any required external dependencies to enable local development (see below).\n* `docker-compose.yml` - this spins up a full DLCS stack, including dotnet components.\n\n```bash\n# start full stack\ndocker-compose up\n\n# start external dependencies only for local dev\ndocker-compose -f docker-compose.local.yml up\n```\n\n### Local Development\n\nBoth docker-compose files will spin up a Postgres, [LocalStack](https://github.com/localstack/localstack) container and external resources like image-servers etc. Postgres connection details are specified via `.env` file (see `.env.dist` for example) and this is listening on `:5452`. The LocalStack image will contain required resources, see [seed-resources.sh](./compose/localstack/seed-resources.sh) and these will be used by DLCS for S3 access.\n\nUsing the connection and AWS details from `.env.dist` and `appsettings.Development.Example.json` will work by default. The `seed-resources.sh` file will seed AWS resources and EFMigrations will be run on Orchestrator startup is `\"RunMigrations\"` appsetting is `true`.\n\n\u003e Note that full stack cannot be run until all elements have been sufficiently implemented.\n\n#### LocalStack \n\nUse of LocalStack can be controlled by appsettings:\n\n```json\n{\n    \"AWS\": {\n        \"Region\" : \"us-east-1\",\n        \"Profile\": \"Used for running against AWS\",\n        \"UseLocalStack\": true,\n        \"S3\": {\n            \"ThumbsBucket\": \"dlcs-thumbs\"\n        }\n    }\n}\n```\n\nUse helpers from `DLCS.AWS` rather than AWS SDK for registering dependencies, e.g.:\n\n```cs\n// Use built in helpers\nservices\n  .SetupAws(configuration, webHostEnvironment)\n  .WithAmazonS3();\n\n// Rather than default SDK methods\nservices\n  .AddDefaultAWSOptions(configuration.GetAWSOptions())\n  .AddAWSService\u003cIAmazonS3\u003e()\n```\n\nIf `environment.IsDevelopment() \u0026\u0026 awsSettings.UseLocalStack;` when the above will register amazon sdk dependencies using LocalStack rather than AWS.\n\n```bash\n# view thumbs bucket\naws s3 ls dlcs-thumbs --recursive --human-readable --endpoint-url=http://localhost:4566\n```\n\n#### Database\n\nRunning Orchestrator with appSetting `RunMigrations = true` will apply migrations to DB on startup.\n\nRunning the `TestData` app will seed data to database.\n\n```bash\ndotnet run ./Utils/TestData/TestData.csproj\n```\n\n\u003e Note that the seed data added by `TestData` is insufficient to fully run DLCS and will need expanded.\n\nMigrations are added using:\n\n```bash\ndotnet ef migrations add \"Table gains column\" -p DLCS.Repository -s API\n```\nif you would like to view the SQL the migration will produce, you can use the following command:\n\n```bash\ndotnet ef migrations script -i -o .\\migrate.sql -p DLCS.Repository -s API\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdlcs%2Fprotagonist","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdlcs%2Fprotagonist","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdlcs%2Fprotagonist/lists"}