Skip to content

Architecture Decision Records πŸ“ƒ

Hendrik Oenings edited this page Jul 9, 2025 · 26 revisions

2025-07-08 Manage ADRs with Git

Status

Accepted.

Context

Currently, ADRs are managed in a single GitHub wiki page of POLAR.

Decision

We move the ADRs to the repository in a documentation folder. We write one file per ADR.

Consequences

  • (+) Changes to ADRs can more comfortably be tracked via Git.
  • (o) There is more overhead in creating and updating ADRs, which may lead to writing less of them.

2025-07-08 Use Pug engine for HTML pages

Status

Declined.

Context

Currently, we write plain HTML as the <template> part of Vue SFCs.

Decision

We use the templating engine Pug for writing <template>s in Vue SFCs.

HTML pages as demos for the clients stay as they are for now.

Consequences

  • (+) Pug has a readable and concise syntax, whereas HTML is very verbose.
  • (+) Pug enforces correct indentation.
  • (-) We introduce additional dependencies.
  • (-) Developers who are already used to writing HTML need to get used to Pug.

2025-07-08 Split customer-specific clients into separate repositories

Status

Accepted.

Context

The new architecture, as introduced by ADR xxxx, has a generic NPM package (@polar/polar, which replaces the packages @polar/core, @polar/lib-X, @polar/plugin-X and @polar/client-generic) and several customer-specific clients (@polar/client-X).

The customer-specific clients are developed because of individual contracts and are (usually) not of major interest for other users. The maintenance of these clients is done primarily for the customers and does not contribute to the project's vision.

Decision

Customer-specific clients (i.e., clients that are not the snowbox or the generic client) are moved to separate repositories (one repository per client).

The new structure shall ensure that core changes can still be developed against a customer-specific client using HMR.

Consequences

  • (+) The repository structure is easier to understand (no monorepo).
  • (+) Rules for contributions can be different between core and clients.
  • (+) Contributors do not have to deal with customer-specific clients.
  • (+) Real-world examples for implementing your own client in your own repository are provided.
  • (+) Generating SBOMs is easier.
  • (-) Following up with updates needs to be done in different repositories.
    • (+) However, SemVer is used and helpers such as renovate exist.
  • (o) Documentation of breaking changes including a migration guide is necessary.

2025-02-24 Revoke "2023-11-07 Plugin-based architecture" regarding packaging

Status

Accepted.

Context

The current structure uses NPM packages so segment the codebase into reusable parts. These packages have no known outside usage and slow down development in various positions as well as make documentation and changelogs a burden. Instead of a differentiation of core, plugins, and libs, all of these parts shall reside in a single package whilst maintaining the current pluginability feature. This single package shall also offer a default modulith client with all parts readymade for instantiating that can optionally be used.

If accepted, the original ADR shall gain an additional sentence linking to this ADR regarding this future change, as this won't be executed easily, in a short time, or in a single step.

Decision

We will restructure the architecture as shown in the next big major version.

Consequences

  • (+) Easier maintenance (no superfluous changelogs, easier type access, less boilerplate, faster releases).
  • (+) Easier to understand the codebase.
  • (-) It's not possible to use different versions of packages in the same client, especially old versions.
    • (+) We never did this anyway and it may have produced complex fix scenarios (LTS for majors?) that no longer may occur.
  • (-) We'll have to introduce technical limitations (architecture checks) regarding imports to prevent the codebase structure from degrading to spaghetti.

2024-08-05 Configuration parameters in tables have to be ordered by a) required and b) alphabetically.

Status

Accepted.

Context

If a developer is reading the docs, having the configuration parameters order first by required values then alphabetically makes it easier to find relevant parameters.

Decision

All docs shall be sorted as proposed.

Consequences

  • (+) Better readability of documentation.
  • (+) Clear placement of new parameters.
  • (-) This restriction must be manually enforced.

2024-03-05 How to expose additional exports of a package

Status

Accepted.

Context

There are multiple ways of exposing additional exports of a package. They can either be exposed in the main file or configured as additional export nodes via rollup and the package.json.

Decision

All exports should be exposed through the main file of the package as additional named exports.

Consequences

  • (+) A package consumer does not need to know additional paths to import.
  • (+) This pattern is established by most major frameworks.
  • (-) This restriction must be manually enforced.

2024-01-10 console statement standardization

Status

Accepted.

Context

In production environments it may seem unclear if an error or warning message is shown in the console from which part of the application they occurred.

Decision

All console.warn and console.error messages have to include the package in which they are invoked.

Consequences

  • (+) Errors and warnings can more easily be tracked back to the place in which they occur.
  • (-) This restriction must be manually enforced.

2024-01-02 Difference between actions, utils and lib-packages

Status

Accepted.

Context

actions, utils and lib-packages can often consist of very similar code. It was not always clear enough where to place certain functionality, which was ultimately up to each developers own preference.

Decision

When deciding on where to place code (when writing or refactoring), the following ordered list should be followed:

  • Does the functionality also change some part of the state? action
  • Should the functionality be usable outside of an integrated client? action
  • Does the functionality not have state changes, but belongs to a certain action? Either locally in the same file as the action or in a folder named after the action in the path store/ACTIONNAME
  • Does the functionality not have state changes, but be reusable in the plugin / core? utils
  • Should the functionality be reusable for multiple plugins / the core? lib-package

Consequences

  • (+) Gives clarity on where specific code fragments should reside.
  • (-) This restriction must be manually enforced.

2023-12-01 Vuex mutations have no map side effects

Status

Accepted.

Context

OL Map interactions are usually side effects by nature, but are not asynchronous. It was unclear whether such changes belong to actions or mutations.

Decision

It has been decided that map side effects do not belong to mutations, but to actions.

Consequences

  • (+) Mutations stay clean of side effects.
  • (+) On potential extension of such map calls, asynchronous behaviour may be required; in that case, actions are already the correct position.
  • (-) This restriction must be manually enforced.

2023-11-29 Error toasts have to be dismissed manually

Status

Accepted.

Context

Information relevant for the user is displayed in toasts which close automatically after a custom timeout.

Decision

A timeout set for toasts that contain error messages will be ignored. Such toasts can only be closed manually by clicking the close button.

Consequences

  • (+) The user is forced to handle error messages and thus is more aware of errors that occur.

2023-11-07 Plugin-based architecture

Status

Accepted. Reverted. https://github.com/Dataport/polar/wiki/Architecture-Decision-Records-%F0%9F%93%83#2025-02-24-revoke-2023-11-07-plugin-based-architecture-regarding-packaging

Context

With recurring requirements, a desire grows to avoid repetition and reuse components. This can be implemented with a plugin-based architecture to create new map clients and have the most common features already done.

Decision

An architecture for the client has been designed that models how we get to re-use functionality without re-writing it while still being open for extensions. The following graphic explains the architecture in further detail.

polar-2-architecture

Consequences

  • (+) Higher quality of features since multiple parties use them.
  • (+) Implement once, use multiple times.
  • (+) Parts are easier to exchange/develop, and not all clients are required to update immediately.
  • (-) More difficult to understand the codebase.

2023-11-07 We write ADRs from now on

Status

Accepted.

Context

As time goes by, it becomes unclear whether architectural decisions have been made accidentally or on purpose, and, if on purpose, what the motivations were.

Decision

From now on, all greater or debatable architectural decisions shall be denoted as an ADR within this document, like the "example ADR" you are currently reading. The used template is from here. Also, questions arising about architecture shall be answered in such an ADR format to procude future references.

Consequences

  • (+) Architecture decisions will become more transparent and understandable.
  • (+) A truth base is defined and referencable.
  • (-) Time needed for documentation.