Commit Graph
2387 Commits
Author SHA1 Message Date
Anthony LC b8f0daab1f 👷(CI) add mcp jobs
Wire up the corresponding build-and-push-mcp jobs
in the Docker Hub and GHCR workflows.
2026-09-11 15:23:34 +02:00
Anthony LC c9412f525b 🧑‍💻(makefile) add helper command for the docs-mcp
We added some helper commands to the Makefile to
facilitate the development of the docs-mcp.
These commands allow developers to easily
connect to the docs-mcp server with your
favorite LLM.
You can start the MCP Inspector with
`make mcp-inspector` to connect to the docs-mcp server and
inspect the different endpoints and their responses.
2026-09-11 15:23:34 +02:00
Anthony LC c91aae078a 🧑‍💻(mcp) add an mcp-inspector helper
Add a `yarn mcp-inspector` script that launches
`@modelcontextprotocol/inspector` against the local
docs-mcp server, with a checked-in config pre-filling
the URL and the `docs-mcp-client`
OAuth client and scopes so there is nothing to type
in by hand.
2026-09-11 15:23:34 +02:00
Anthony LC f9e30f1ccc (mcp) add the docs-mcp server
Add `src/frontend/servers/mcp`, a stateless TypeScript (Express +
`@modelcontextprotocol/sdk`) MCP server exposing `search_documents`,
`read_document` and `create_document` over Streamable HTTP.

It is an OAuth resource server holding no credentials of its own: it
verifies the caller's Keycloak token against the realm JWKS
(`src/auth/jwtVerifier.ts`), checks the `docs-mcp` audience, then
forwards the same token unchanged to Django's
`/api/v1.0/mcp/documents/*` endpoints (`src/docsApiClient.ts`),
which stays the sole authority on document permissions.
No token exchange.

Ship the `mcp-development` compose service, its `env.d/development/mcp`
env file, a `build-mcp` Makefile helper, and
`documentation/mcp_server.md` describing the full flow and
how to connect MCP clients.
2026-09-11 15:23:34 +02:00
Anthony LC 5d74c10aa0 🔧(keycloak) configure realm for the MCP server
Add to the dev realm:

- `docs-mcp-client`, the public PKCE client MCP clients authenticate
  with, with optional scopes `docs:documents:{search,read,create}` and
  `docs-mcp`.
- `docs-api`, the confidential client Django uses as introspection
  credentials (`OIDC_RS_CLIENT_ID/SECRET`).
- the `docs:documents:*` consent scopes and a `docs-mcp` audience-mapper
  scope that stamps the `docs-mcp` audience only when requested.

Point the resource-server env at the `impress` realm and the new
clients, allow the `docs-mcp-client` audience, and grant users
`offline_access` for refresh tokens.
2026-09-11 15:23:00 +02:00
Anthony LC e7fb8fa211 (backend) add basic mcp api for document
We added a basic MCP API to the backend.
This API is designed to facilitate integration with external
systems, providing a secure and efficient way to
access document data.

API endpoints include:
- POST /api/v1.0/mcp/documents/search  -> search_documents
- GET  /api/v1.0/mcp/documents/<id>    -> read_document
- POST /api/v1.0/mcp/documents         -> create_document
2026-09-11 15:23:00 +02:00
Manuel Raynaud 00cc95aa05 🔧(backend) move the DockerflowMiddleware higher in the middleware list
We decided to move the DockerflowMiddleware higher in the middleware
list to prevent future access to the database or redis in other
middleware that can have an impact on the liveness probe.
2026-09-11 12:55:20 +02:00
Manuel Raynaud 451499016e ️(backend) increase nb_accesses cache TTL
The nb_accesses cache TTL was very short, 30 seconds. That mean that the
user will hit the cache for a very short period and the cache is
probably not be hit. This is what we can see in the slow queries from
the pg_stat_statements table. The query to compute the nb_accesses is
executed a little bit less than the number of queries to list or
retrieve documents, meaning the cache is not used.
2026-09-11 12:55:20 +02:00
Manuel Raynaud 6baf20aaeb ️(backend) improve DocumentViewset.get_queryset
The filtering made in the DocumentViewset.get_queryset method is not
optimal and lead to a full scan of the Document table. The heavy part is
on the filtering on what the user can access between the accesses and
the link traces. To have better performance we make an union operation
of both document_id list and the filter the id on this list. Postgresql
will use the index on the id column.
2026-09-11 12:55:20 +02:00
Manuel Raynaud fbc3ef83ba ️(backend) stop using LEFT(value, LENGTH(path)) in sql queries
Comparing path with LEFT(value, LENGTH(path)) makes a sequential scan on
all the Document table, the more this table grow, the more the query
using it will be slow. We dediced instead to lookup on the path
extracting all ancestors path for a given document and then make a path
IN statement to use the index existing on the path column.
2026-09-11 12:55:20 +02:00
Anthony LC afc11adc52 🐛(y-provider) prevent process crash on malformed websocket frames
The ws library emits an unhandled 'error' event when a client sends a
frame with unexpected RSV bits (e.g. permessage-deflate mismatch),
which was crashing the whole y-provider process since no listener was
attached to the socket. Add an error listener to log and drop the
offending connection instead.
2026-09-11 10:57:25 +02:00
Anthony LCandOvgodd e68c604ead (e2e) fix flaky test
A test got suddenly very flaky, we fixed it
by reloading the page to ensure that the config
was properly overridden.
2026-09-11 08:59:18 +02:00
Cyril 9ebca52361 ️(frontend) restore presenter focus trapping after share links
Restore FocusScope and aria-disabled for access presenter nav after share links
2026-09-11 08:59:18 +02:00
renovate[bot]andGitHub 17c03b5da0 ⬆️(dependencies) update @ai-sdk/openai to v3.0.106 2026-09-10 08:17:10 +00:00
Manuel RaynaudandGitHub 673a670dd9 🔧(backend) configure request.summary logger
The request.summary logger is used by dockerflow. The INFO level is
always empty and is used everytime the liveness or readiness endpoint
are fetch.
2026-09-09 14:46:19 +00:00
Ovgodd bcc1eb9faf 🐛(frontend) hide the selection highlight on presenter images
Presenter reset no longer hid selection; image slides appeared focused on open.
2026-09-09 15:10:06 +02:00
renovate[bot]andGitHub d8e5d5e796 ⬆️(dependencies) update sharp to v0.35.4 [SECURITY] 2026-09-09 09:54:31 +00:00
renovate[bot]andGitHub 64b23e864b ⬆️(dependencies) update next to v16.3.3 [SECURITY] 2026-09-09 01:43:59 +00:00
Manuel Raynaud 137cecc0e1 🔧(backend) fine tune redis cache options
We want to configure other options on the redis cache. By default there
is no timeout on the connection to socket and no timeout for read/write
operations. We set default values in all caches used in production. The
settings IGNORE_EXCEPTIONS differ between the default and the session
cache. Activating it behaves like a missed cache. Enabling it for the
session should lead to unwanted side effects, by returning falsy on the
session creation, a retry mechanism of 10000 attempts is made in the
SessionStore.create method, the request can stay in this loop for a long
time.
2026-09-08 16:26:15 +02:00
Manuel Raynaud 0b8808f9a7 🐛(backend) skip session creation for the readiness probe
The readiness probe should also not create a new session. A new session
will live in redis and increase the number of keys inside it for
nothing. The readiness path is isgnored in the ForceSessionMiddleware
2026-09-08 14:44:57 +02:00
Manuel Raynaud 36a890a119 ⬆️(backend) upgrade celery to version 5.6.3
Celery version 5.6 has several fixes we want : two significant memory
leaks have been resolved and also a fix allowing a better use of psycopg
pool.
2026-09-08 14:44:56 +02:00
Anthony LC 5728fcdfbc (e2e) webp image with export tests
We added a new webp image to the e2e tests and updated the export
tests to include this new image format.
This ensures that the export functionality correctly
handles webp images, maintaining compatibility and
performance across different image formats.
We increase throttles, to be sure that the e2e tests
don't hit them.
2026-09-08 12:10:08 +02:00
Mathieu AgopianandAnthony LC ebde46109f (frontend) add an e2e test for complex PNG exports
In order to ensure that complex PNG images are
exported correctly, we have added an end-to-end
test that verifies the export functionality.
This test will help catch any regressions related
to image exports in future updates.

Signed-off-by: Mathieu Agopian <mathieu@agopian.info>
2026-09-08 12:10:08 +02:00
Mathieu AgopianandAnthony LC fa2757f282 📝(frontend) Add some docstrings
Add docstrings to improve code documentation and clarity.

Signed-off-by: Mathieu Agopian <mathieu@agopian.info>
2026-09-08 12:10:07 +02:00
Mathieu AgopianandAnthony LC a5f26434ba 🐛(frontend) export any raster image supported by the browser to a PDF
WebP format isn't supported by react-pdf/renderer and so wasn't exported
properly, and some PNG images were also not exporting.
First drawing those raster images to a canvas and providing a dataURL to
react-pdf/renderer fixes those two bugs at once.

Signed-off-by: Mathieu Agopian <mathieu@agopian.info>
2026-09-08 12:10:07 +02:00
Manuel Raynaud 8ec3ae880f 🙈(docker) ignore **/.venv files
Since we migrated to uv, the venv folder does not live anymore at the
project root but inside the src/backend directory. Add a rule in the
.dockerignore to ignore it.
2026-09-08 08:56:58 +02:00
Manuel Raynaud 1e61b4a789 🐛(backend) skip session creation for the liveness probe
The ForceSessionMiddleware force the session creation, we want to
ignore it when the request is the liveness probe. The liveness probe
must not check if redis is available, this is the readiness probe job
2026-09-08 08:56:42 +02:00
Ovgodd 050a584e7b 💄(frontend) redesign email confirmation standalone page
Email confirmation is a business page and now uses the shared chrome.
2026-09-07 10:24:57 +02:00
Ovgodd 07c2323499 ♻️(frontend) extract shared footer actions and bar
Footer actions lived in the left panel and could not be reused elsewhere.
2026-09-07 10:24:57 +02:00
Ovgodd 63e5b53868 ♻️(frontend) extract shared header logo and bar
The Docs logo lived in the left panel and could not be reused elsewhere.
2026-09-07 10:24:57 +02:00
fch-aaandAnthony LC 1f126cf629 🐛(frontend) preserve title when adding an emoji
The emoji action could reuse a stale document title while a rename was being
submitted, replacing the new title with the emoji alone.

Keep the latest submitted title in the header and cover the interaction
with a regression test.

Signed-off-by: fch-aa <21101725+fch-aa@users.noreply.github.com>
2026-09-07 09:27:57 +02:00
Manuel Raynaud 3c1275c88d 🔖(release) patch 5.6.1
Added

- (frontend) export presenter slides as PDF #2487

Fixed

- 🐛(frontend) hide Leave in the doc menu when not logged in #2626
- 🐛(backend) allow to configure settings DATA_UPLOAD_MAX_MEMORY_SIZE
v5.6.1-preprod v5.6.1
2026-09-04 18:19:06 +02:00
renovate[bot]andGitHub 36bf78558a ⬆️(dependencies) update django to v5.2.16 [SECURITY] 2026-09-04 16:05:54 +00:00
Anthony LC 9c46048f0f (e2e) try to fix flakiness on e2e tests
We improve a test to try to reduce flakiness.
We increase the throttles, to be sure that the e2e
tests don't hit them.
2026-09-04 17:41:00 +02:00
Manuel Raynaud efdac7444d (backend) add servestatic dependency
We removed previously whitenoise because it was not working with asgi
application. By removing it we also removed the way to serve the static
files in the application. There is an existing fork of whitenoise,
servestatic, that manage async application and we can use it to serve
static files.
2026-09-04 16:28:16 +02:00
Nathan Panchout 1debd291d8 (frontend) cover presenter PDF export
Exercise PDF print pages, file blocks, and tall slide clipping.

Keep coverage scoped to the presenter export workflow.
2026-09-04 11:35:24 +02:00
Nathan Panchout b67039dc6c (frontend) export the presentation as a PDF
Render the slides off-screen as A4 landscape pages and print them via
the browser, one slide per page with the watermark. Add a "Download PDF"
action to the floating bar.

Closes #2446
2026-09-04 11:35:24 +02:00
Nathan Panchout eb6a0db31b (frontend) add a docs logo watermark to presentations
Show a monochrome Docs logo in the slide corner (web and PDF) to signal
the document was made with Docs.

Closes #2472
2026-09-04 11:35:24 +02:00
Nathan Panchout f3dc31c13d ♻️(frontend) let print DOM helpers target a custom root
wrapMediaWithLink / wrapInterlinksWithAnchor defaulted to document.
Accept a root node so the presenter export can reuse them on its
off-screen tree.
2026-09-04 11:35:24 +02:00
Manuel Raynaud 3bede0d9a0 🐛(backend) allow to configure settings DATA_UPLOAD_MAX_MEMORY_SIZE
Release 3.17.2 of DRF now takes care of DATA_UPLOAD_MAX_MEMORY_SIZE
and is checked when the body request is parsed. Before that, DRF wasn't
using it at all and we were only looking for custom settings linked to
the media and conversion file upload. We must now also configure this
setting.
2026-09-04 10:21:43 +02:00
MoraandAnthony LC b32b3f08c2 🐛(frontend) hide leave option when unauthenticated
Leave was shown in the document menu for anonymous visitors.
Hide it unless the current user can actually leave the doc.

Signed-off-by: Mora <razvi.morariu.mihai@gmail.com>
2026-09-04 09:04:12 +02:00
Anthony LC 059f1d004a 🔖(release) minor 5.6.0
Added:
- (frontend) Add "Copy link to block" feature
- (frontend) add word count to doc header toolbox
- (frontend) add find and replace feature to the editor

Changed:
- ️(frontend) use anchor links for interlinking sub-documents
- (frontend) reset side panel state between documents
- ️(frontend) announce search loading state for screen readers
- ♻️(frontend) change favorite to star
- 🚚(frontend) add doc move to doc options
- ♻️(frontend) unified menu
- (frontend) hide decorative emojis in document titles from SR
- ♻️(frontend) save the doc with a keepalive request when
  leaving the page

Fixed:
- 🐛(frontend) fix clipped formatting toolbar in new comment
  composer
- 🐛(backend) fix duplicating a document that has no content
- 📄(frontend) allowed partially export when MIT
- 🐛(backend) manage async support for Docs custom middleware

Removed:
- 🔥(backend) remove whitenoise package
v5.6.0-preprod v5.6.0
2026-09-03 17:00:36 +02:00
Anthony LC 75fe97272f 🐛(frontend) codeblock throws errors when unsupported language
Implementation of code block throws a errors when a `language` prop
is not supported by BlockNote, which crashes the whole editor.
In our case, the language is supported but flagged as an alias
(e.g. `js` instead of `javascript`),
but Blocknote does not resolve aliases and throws an error.

This file wraps the code block spec to normalize the `language`
prop before BlockNote renders it,
so a single legacy code block does not crash the whole editor.
2026-09-03 17:00:36 +02:00
AntoLCandAnthony LC 8b9fce27fd 🌐(i18n) update translated strings
Update translated files with new translations
2026-09-03 17:00:35 +02:00
Anthony LC ceae767825 ♻️(frontend) adapt side menu with Blocknote 0.54.0
Blocknote changed the way the side menu is positioned.
Because we are modifying the height of the heading blocks
we need to adjust the offset of the side menu to match
the new height of the heading blocks.
To do so we have to override the default offset of
the side menu with a custom offset that takes into
account the new height of the heading blocks.
2026-09-03 13:30:49 +02:00
Anthony LC 7c106e33a8 🔒️(js) fix security warning
- browserslist
- nanoid
2026-09-03 13:30:48 +02:00
Anthony LC ee624e875e (frontend) add math and diagram blocks to the editor
Last version of Blocknote added support for math
and diagram blocks. This commit updates the
dependencies to include the necessary toolbar
items to create math and diagram blocks in
the editor.
2026-09-03 13:30:47 +02:00
Anthony LC ac580bc81b 🚨(frontend) adapt codebase to Blocknote 0.54.0
We bumped Blocknote to 0.54.0, which introduced
some breaking changes. This commit adapts our
codebase to the new API and ensures compatibility
with the latest version of Blocknote.
2026-09-03 11:07:27 +02:00
renovate[bot]andAnthony LC 0e8bc3a518 ⬆️(dependencies) update js dependencies 2026-09-03 09:15:26 +02:00
Manuel Raynaud b12b3b5dd6 🐛(frontend) save the doc with a keepalive request when leaving the page
Since we fix the error in the backend application coming from middleware
not managing async request lifecycle, the e2e tests were failing. This
is because the browser cancel the request when made in the beforeunload
event. To fix it, we set the keepalive property on the fetch method to
True to not abort the request when the page is unloaded.
2026-09-03 08:25:15 +02:00