Skip to content

docs: architecture decision records - #347

Open
tuj wants to merge 6 commits into
developfrom
feature/architecture-decision-records
Open

docs: architecture decision records#347
tuj wants to merge 6 commits into
developfrom
feature/architecture-decision-records

Conversation

@tuj

@tuj tuj commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Link to ticket

https://leantime.itkdev.dk/?tab=timesheet#/tickets/showTicket/8000

Description

Adds docs/adr/ with nine Architecture Decision Records, and trims CHANGELOG.md now that
there is somewhere for design reasoning to live.

Why. Several decisions in this codebase read as oversights until you know the constraint
behind them — the hand-built Leantime HTTP client, retry logic deliberately spread across three
files, deleteAll() pinned to the sync transport, two soft-delete mechanisms on the same
entities. Nothing in the repo explained any of it, so the reasoning had been accumulating in the
changelog instead: PR-340 spent 26 lines on Messenger's service-reset semantics, PR-327 spent 33
across six bullets. Anyone scanning for "what changed in 3.8.0" had to read a design document to
find out.

The ADRs give that reasoning a home. The changelog goes back to being a list of changes.

The nine records. All document decisions already live in the code — nothing here changes
behaviour:

# Decision
001 One data provider abstraction, Leantime as the only implementation
002 Data provider credentials live in the database
003 Synchronisation is Messenger-paged, and the transport choice is semantic
004 Retry policy is split across three layers on purpose
005 Soft-delete-by-source, tracked separately from the entity's own deletion
006 Doctrine ORM 2, Copenhagen-local datetimes, and a global soft-delete filter
007 Reports go form data in, report data out, through typed DTOs
008 The test bootstrap rebuilds the database; no DAMADoctrineTestBundle
009 PHPStan level 8, with a baseline that is never regenerated

docs/adr/README.md carries the index and the conventions for adding the next one.

Changelog cleanup. Scoped to [Unreleased] and every 3.x section; 2.x and 1.x were already
one-line bullets and are untouched. 73 insertions, 175 deletions — 902 lines down to 800.

  • Every entry in scope is now one or two lines, three at the most.
  • Design reasoning moved into the ADR that owns the topic, with a See [ADR 00N](…) link left in
    its place.
  • Removed the five bullets that only announced a test file or test case. Test tooling stayed:
    the 62% coverage gate, task test:coverage:set-threshold, the fixtures:load speedup.
  • Dropped one duplicate — PR-302 and PR-306 both claimed the messenger_messages schema_filter
    exclusion within the same release.

On the approach: the extracted reasoning went into the four existing ADRs that already owned
each topic, rather than into new records. ADR 002 gained why the provider URL is normalized where
it is read (Doctrine hydrates properties directly, so a setter would miss existing rows); 003
gained the row-level skip rule, which is the opposite of its page-level one and easily confused
with it; 004 absorbed the most — where the 429s actually came from, ThrottlingHttpClient as a
rejected option, and the whole closed-EntityManager / dead-socket / ping-middleware argument;
005 gained why the source's own modifiedAt is not trusted and what the nightly -d jobs are for.

Two things worth a reviewer's eye:

  • PR-344 appeared twice in [Unreleased] — once for the ADRs, once for the sync
    include-filter fix. Merged under one heading, but one of those numbers is probably wrong.
  • PR-332's CI entry lost its rationale rather than moving it: that no job needs RabbitMQ
    because when@test routes the only AMQP transport to Doctrine. It had no ADR to go to and is
    recoverable from config/packages/messenger.yaml, but it is the one place where trimming cost
    an explanation instead of relocating it.

Checklist

  • My code is covered by test cases. — n/a, no code changed
  • My code passes our test (all our tests). — no PHP touched, suite unaffected
  • My code passes our static analysis suite. — no PHP touched, PHPStan unaffected
  • My code passes our continuous integration process. — markdownlint verified locally;
    the changelog gate passes, since CHANGELOG.md differs from develop

@tuj tuj self-assigned this Aug 27, 2026
@tuj tuj changed the title feat: architecture decision records docs: architecture decision records Aug 27, 2026
@tuj
tuj requested a review from jeppekroghitk September 8, 2026 11:48
@tuj tuj added the documentation Improvements or additions to documentation label Sep 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant