> For the complete documentation index, see [llms.txt](https://docs.opendatadiscovery.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.opendatadiscovery.org/developer-guides.md).

# Developer Guides

- [Architectural Decision Log](https://docs.opendatadiscovery.org/developer-guides/architecture-decision-log.md): Architecture Decision Records for ODD Platform — the significant decisions the codebase embodies, reconstructed from the source with the code evidence to verify each one.
- [ADR-0001: Contract-first HTTP layer](https://docs.opendatadiscovery.org/developer-guides/architecture-decision-log/adr-0001-openapi-generated-controller-interfaces.md): ODD Platform's REST controllers are thin delegates over OpenAPI-generated interfaces — the HTTP contract lives in the spec, and routes change by regenerating it, not by editing controllers.
- [ADR-0002: Centralised path-matcher authorization](https://docs.opendatadiscovery.org/developer-guides/architecture-decision-log/adr-0002-centralised-path-matcher-authorization.md): ODD Platform centralises endpoint authorization in one path-matcher rule table — controllers carry no @PreAuthorize, so the entire access matrix lives in one auditable place.
- [ADR-0004: GenAI ships disabled by default](https://docs.opendatadiscovery.org/developer-guides/architecture-decision-log/adr-0004-genai-disabled-by-default.md): ODD Platform ships GenAI off by default — a runtime guard rejects requests until an operator sets genai.enabled and supplies the url and timeout, which have no working defaults.
- [ADR-0007: Uniform reactive controller pipeline](https://docs.opendatadiscovery.org/developer-guides/architecture-decision-log/adr-0007-uniform-reactive-controller-pipeline.md): ODD Platform's reactive controllers share one shape — methods return Mono\<ResponseEntity\<T>> via ResponseEntity::ok, and error translation is centralised in a single advice class.
- [ADR-0008: OpenAPI tags scope the generated API interfaces](https://docs.opendatadiscovery.org/developer-guides/architecture-decision-log/adr-0008-openapi-tag-per-resource-scoping.md): Every ODD Platform OpenAPI operation carries exactly one tag, and the generator emits one Java interface per tag — so a tag is the unit that shapes the generated \*Api interfaces.
- [ADR-0012: Attachment storage backend is selected at boot](https://docs.opendatadiscovery.org/developer-guides/architecture-decision-log/adr-0012-attachment-storage-backend-boot-selection.md): ODD Platform picks its attachment storage backend at boot from attachment.storage — LOCAL is the implicit default, REMOTE is S3/MinIO, and switching backends needs a restart.
- [ADR-0018: Outbound-integration config is fail-fast at boot](https://docs.opendatadiscovery.org/developer-guides/architecture-decision-log/adr-0018-fail-fast-outbound-config-at-boot.md): ODD Platform validates an outbound integration's config when its bean is built — a missing value fails startup, not the first message; an unconfigured channel is simply off.
- [ADR-0019: Data Collaboration ships disabled by default](https://docs.opendatadiscovery.org/developer-guides/architecture-decision-log/adr-0019-data-collaboration-disabled-by-default.md): ODD Platform ships Data Collaboration off by default — a conditional gates the whole controller on datacollaboration.enabled, so every route returns 404 until an operator opts in.
- [ADR-0020: Outbound Slack delivery is decoupled via a Postgres queue](https://docs.opendatadiscovery.org/developer-guides/architecture-decision-log/adr-0020-decoupled-outbound-slack-delivery.md): ODD Platform accepts a Slack message with 202, persists it, and delivers it from a background worker that holds a Postgres advisory lock — so delivery needs no message broker, only Postgres.
- [ADR-0040: Notifications ship disabled by default behind one condition](https://docs.opendatadiscovery.org/developer-guides/architecture-decision-log/adr-0040-notifications-disabled-by-default.md): ODD Platform ships notifications off by default — one Condition reads notifications.enabled and a single meta-annotation gates every component, so the whole subsystem turns on from one switch.
- [ADR-0041: Notification channels activate by the presence of their keys](https://docs.opendatadiscovery.org/developer-guides/architecture-decision-log/adr-0041-notification-per-channel-presence-activation.md): Each notification channel — Slack, webhook, email — turns on by the presence of its own config key; an unset key means no bean and no delivery, with no separate per-channel enable flag.
- [ADR-0042: Notification fan-out is fail-soft per channel](https://docs.opendatadiscovery.org/developer-guides/architecture-decision-log/adr-0042-notification-fail-soft-fan-out.md): When ODD Platform fans an alert out to its notification channels, a failure in one channel is logged and the rest still receive it — one broken channel never blocks the others.
- [ADR-0043: The notification WAL consumer is a leader-elected singleton](https://docs.opendatadiscovery.org/developer-guides/architecture-decision-log/adr-0043-notification-wal-single-leader.md): ODD Platform consumes the Postgres WAL for notifications from one thread on one replica, elected by a Postgres advisory lock — so a multi-replica deployment emits each alert once, with no broker.
- [ADR-0044: Postgres replication artefacts are lazy-created, never dropped](https://docs.opendatadiscovery.org/developer-guides/architecture-decision-log/adr-0044-postgres-artefact-lazy-create-no-drop.md): ODD Platform creates its notification replication slot and publication on first run if absent, but never drops them — cleanup is the operator's responsibility, by design.
- [ADR-0021: Activity streams use cursor pagination](https://docs.opendatadiscovery.org/developer-guides/architecture-decision-log/adr-0021-activity-stream-cursor-pagination.md): ODD Platform paginates its append-only activity streams by a (lastEventId, lastEventDateTime) cursor rather than offset/limit — list endpoints keep offset paging; the shape follows the data.
- [ADR-0022: Activity view-modes are a single enum parameter](https://docs.opendatadiscovery.org/developer-guides/architecture-decision-log/adr-0022-activity-view-modes-single-parameter.md): The activity feed selects its view (all / my objects / upstream / downstream) with one ActivityType enum parameter dispatched server-side, rather than a separate endpoint per view.
- [ADR-0028: High-volume tables are range-partitioned ahead of need](https://docs.opendatadiscovery.org/developer-guides/architecture-decision-log/adr-0028-range-partition-lifecycle.md): ODD Platform creates range partitions ahead of need — one job runs at boot (Postgres advisory lock) and nightly (ShedLock), making double-width partitions per high-volume table.
- [ADR-0045: Housekeeping is a separate subsystem from partition management](https://docs.opendatadiscovery.org/developer-guides/architecture-decision-log/adr-0045-housekeeping-partition-separation.md): ODD Platform separates TTL row-cleanup (housekeeping) from partition creation; the one bridging task, dropping empty partitions, lives in housekeeping but calls the partition service.
- [ADR-0046: Housekeeping ships enabled by default (opt-out)](https://docs.opendatadiscovery.org/developer-guides/architecture-decision-log/adr-0046-housekeeping-opt-out-by-default.md): ODD Platform ships data housekeeping on by default — it deletes aged rows out of the box, so bounded DB growth is the default posture and an operator must opt out to keep data indefinitely.
- [ADR-0073: ODDRN is the universal identity for every entity](https://docs.opendatadiscovery.org/developer-guides/architecture-decision-log/adr-0073-oddrn-universal-identity.md): Every entity carries a stable ODDRN string — the same ODDRN always means the same entity across ingests and producers, which is what makes idempotent ingestion and cross-system lineage possible.
- [ADR-0071: PostgreSQL is the only required runtime dependency](https://docs.opendatadiscovery.org/developer-guides/architecture-decision-log/adr-0071-postgres-only-runtime-dependency.md): ODD Platform needs no broker, ZooKeeper, or Redis — queuing, leader election, notifications, lineage, and full-text search are all built on PostgreSQL, the only required runtime dependency.
- [ADR-0070: Ingestion is one wire contract shared by pull and push producers](https://docs.opendatadiscovery.org/developer-guides/architecture-decision-log/adr-0070-pull-push-ingestion-contract.md): Pull collectors poll on a schedule, push adapters emit on the source's cadence; both speak one ODD Specification contract, and the platform processes every payload identically.
- [ADR-0072: The platform is a contract-first, reactive, two-language stack](https://docs.opendatadiscovery.org/developer-guides/architecture-decision-log/adr-0072-contract-first-reactive-stack.md): ODD Platform is a reactive Spring WebFlux + R2DBC backend and a React/TypeScript SPA, with one OpenAPI contract generating both the server interfaces and the browser client.
- [ADR-0003: The catalog is read-collaborative — only mutations are permission-gated](https://docs.opendatadiscovery.org/developer-guides/architecture-decision-log/adr-0003-read-collaborative-authorization.md): Once authenticated, any ODD user can read the whole catalog — entities, lineage, search, activity. Only mutations are permission-gated; reads are authenticated-only by design.
- [ADR-0058: Deletion is soft — DELETED is a status, not a row removal](https://docs.opendatadiscovery.org/developer-guides/architecture-decision-log/adr-0058-soft-delete-deletion-model.md): Deleting a data entity sets its status to DELETED, not removing the row; list and search hide it, the detail view still shows it, and housekeeping physically purges it after a TTL.
- [ADR-0074: Authentication is a pluggable mode selected by auth.type, defaulting to DISABLED](https://docs.opendatadiscovery.org/developer-guides/architecture-decision-log/adr-0074-pluggable-auth-modes.md): Auth is one of four modes set by auth.type (DISABLED, LOGIN\_FORM, OAUTH2, LDAP). It ships DISABLED, which is fully open — enable a real mode for any networked deployment.
- [ADR-0075: Heavyweight features ship off by default; operational-hygiene jobs ship on](https://docs.opendatadiscovery.org/developer-guides/architecture-decision-log/adr-0075-feature-gating-posture.md): Outbound features (GenAI, Data Collaboration, Notifications) ship disabled and need explicit wiring; housekeeping and other hygiene jobs ship enabled, keeping the database bounded.
- [ADR-0076: In-context concept help is an information icon in a hover tooltip](https://docs.opendatadiscovery.org/developer-guides/architecture-decision-log/adr-0076-inline-info-tooltip-affordance.md): Inline help for an ambiguous label is a small information (i) icon wrapped in a hover tooltip carrying a short explanation - the platform's one established affordance, reused rather than reinvented.
- [ADR-0078: Editing a consequential field uses a change-preview confirmation that reduces into the store](https://docs.opendatadiscovery.org/developer-guides/architecture-decision-log/adr-0078-confirm-and-store-reduce-field-edits.md): A field that drives downstream display or semantics (status, DQ severity) is edited via a change-preview confirmation that reduces the result into the store - never an optimistic instant save.
- [ADR-0079: Ingestion authentication is one gate over /ingestion/\*\*, not per-route filters](https://docs.opendatadiscovery.org/developer-guides/architecture-decision-log/adr-0079-ingestion-authentication-filter-coverage.md): When auth.ingestion.filter.enabled=true, a single WebFilter authenticates the whole /ingestion/\*\* surface against a registered collector/datasource token — replacing the two exact-path filters that le
- [API Reference](https://docs.opendatadiscovery.org/developer-guides/api-reference.md): Canonical reference for the ODD Platform HTTP API — hub page with per-feature sub-pages plus the OpenAPI specifications and Swagger UI walkthrough that span the whole API.
- [Alerts](https://docs.opendatadiscovery.org/developer-guides/api-reference/alerts.md): Alert HTTP endpoints — global tab listings, per-entity listings, status mutation, halt-notification configuration, and the inbound AlertManager webhook.
- [Data Collaboration](https://docs.opendatadiscovery.org/developer-guides/api-reference/data-collaboration.md): Data Collaboration HTTP endpoints — outbound to the provider, per-entity threads & history, and the inbound Slack Events webhook. Gated by \`@ConditionalOnDataCollaboration\`.
- [Directory](https://docs.opendatadiscovery.org/developer-guides/api-reference/directory.md): Directory HTTP endpoints — four \`GET\` calls under \`/api/directory\` backing the four-level drill-down (data source types → data sources → entity types → entities).
- [GenAI](https://docs.opendatadiscovery.org/developer-guides/api-reference/genai.md): GenAI HTTP endpoint — proxy natural-language questions to an external AI service through the platform's \`POST /api/genai/ask\`.
- [Glossary](https://docs.opendatadiscovery.org/developer-guides/api-reference/glossary.md): Business Glossary HTTP endpoints — term CRUD + lookup, term-side and resource-side linkage, faceted search, ownership and tags.
- [Integrations](https://docs.opendatadiscovery.org/developer-guides/api-reference/integrations.md): Integration Wizard HTTP endpoints — list registered integrations and fetch their content blocks plus code snippets.
- [Lineage](https://docs.opendatadiscovery.org/developer-guides/api-reference/lineage.md): Lineage HTTP endpoints — per-entity upstream / downstream graphs and group lineage, with \`lineage\_depth\` and \`expanded\_entity\_ids\` query parameters.
- [Query Examples](https://docs.opendatadiscovery.org/developer-guides/api-reference/query-examples.md): Query Examples HTTP endpoints — CRUD, faceted search, and per-entity / per-term lookup and linking. 16 endpoints across three groups.
- [Reference Data](https://docs.opendatadiscovery.org/developer-guides/api-reference/reference-data.md): Lookup Tables HTTP endpoints — Table CRUD, Column CRUD, Row CRUD, and faceted search. 16 endpoints under \`/api/referencedata/\`.
- [Relationships](https://docs.opendatadiscovery.org/developer-guides/api-reference/relationships.md): Relationships HTTP endpoints — paginated list with type filter (ERD / GRAPH / ALL) plus per-type detail endpoints.
- [How to contribute](https://docs.opendatadiscovery.org/developer-guides/how-to-contribute.md): Developer guide for contribution to the OpenDataDiscovery
- [GitHub organization overview](https://docs.opendatadiscovery.org/developer-guides/github-organization-overview.md): Overview of all repositories inside of ODD GitHub organization
- [Build and run](https://docs.opendatadiscovery.org/developer-guides/build-and-run.md): Build-and-run entry point for ODD developers — Platform backend + frontend, the ODD Collectors family, and the SDK path for authoring brand-new collectors / adapters.
- [Build and run ODD Platform](https://docs.opendatadiscovery.org/developer-guides/build-and-run/build-and-run-odd-platform.md): Developer guide on how to build and run ODD Platform backend and frontend
- [Build and run ODD Collectors](https://docs.opendatadiscovery.org/developer-guides/build-and-run/build-and-run-odd-collectors.md): Developer guide on how to build and run ODD Collectors
- [Build a custom collector](https://docs.opendatadiscovery.org/developer-guides/build-and-run/custom-collectors.md): Build a custom ODD collector or adapter against the odd-collector-sdk.
